Skip to content

Commit

Permalink
refactor: merge component and process dbs in-memory. (#903)
Browse files Browse the repository at this point in the history
Merge the 3 process and component JSON db files 
in-memory, dynamically add scopes when decoding JSON
contents to ease filtering them at runtime when required
  • Loading branch information
n1k0 authored Jan 21, 2025
1 parent df47225 commit 02a9793
Show file tree
Hide file tree
Showing 25 changed files with 248 additions and 266 deletions.
4 changes: 2 additions & 2 deletions src/Data/Bookmark.elm
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ toQueryDescription db bookmark =

Object objectQuery ->
objectQuery
|> ObjectQuery.toString db.object.components db.object.processes
|> ObjectQuery.toString db.components db.processes
|> Result.withDefault "N/A"

Textile textileQuery ->
Expand All @@ -215,5 +215,5 @@ toQueryDescription db bookmark =

Veli objectQuery ->
objectQuery
|> ObjectQuery.toString db.object.components db.object.processes
|> ObjectQuery.toString db.components db.processes
|> Result.withDefault "N/A"
8 changes: 4 additions & 4 deletions src/Data/Common/Db.elm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Data.Common.Db exposing

import Data.Country as Country exposing (Country)
import Data.Impact.Definition as Definition exposing (Definitions)
import Data.Textile.Db as TextileDb
import Data.Process exposing (Process)
import Data.Transport as Transport exposing (Distances)
import Json.Decode as Decode

Expand All @@ -17,9 +17,9 @@ impactsFromJson =
>> Result.mapError Decode.errorToString


countriesFromJson : TextileDb.Db -> String -> Result String (List Country)
countriesFromJson textile =
Decode.decodeString (Country.decodeList textile.processes)
countriesFromJson : List Process -> String -> Result String (List Country)
countriesFromJson processes =
Decode.decodeString (Country.decodeList processes)
>> Result.mapError Decode.errorToString


Expand Down
19 changes: 11 additions & 8 deletions src/Data/Component.elm
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module Data.Component exposing

import Data.Impact as Impact exposing (Impacts)
import Data.Process as Process exposing (Process)
import Data.Scope as Scope exposing (Scope)
import Data.Split as Split
import Data.Uuid as Uuid exposing (Uuid)
import Energy
Expand All @@ -55,6 +56,7 @@ type alias Component =
{ elements : List Element
, id : Id
, name : String
, scopes : List Scope
}


Expand Down Expand Up @@ -255,17 +257,18 @@ computeItemResults { components, processes } { id, quantity } =
)


decode : Decoder Component
decode =
decode : List Scope -> Decoder Component
decode scopes =
Decode.succeed Component
|> Decode.required "elements" (Decode.list decodeElement)
|> Decode.required "id" (Decode.map Id Uuid.decoder)
|> Decode.required "name" Decode.string
|> Decode.optional "scopes" (Decode.list Scope.decode) scopes


decodeList : Decoder (List Component)
decodeList =
Decode.list decode
decodeList : List Scope -> Decoder (List Component)
decodeList scopes =
Decode.list (decode scopes)


decodeElement : Decoder Element
Expand All @@ -283,9 +286,9 @@ decodeItem =
|> Decode.required "quantity" (Decode.map Quantity Decode.int)


decodeListFromJsonString : String -> Result String (List Component)
decodeListFromJsonString =
Decode.decodeString decodeList
decodeListFromJsonString : List Scope -> String -> Result String (List Component)
decodeListFromJsonString scopes =
Decode.decodeString (decodeList scopes)
>> Result.mapError Decode.errorToString


Expand Down
35 changes: 13 additions & 22 deletions src/Data/Food/Db.elm
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,28 @@ import Data.Example as Example exposing (Example)
import Data.Food.Ingredient as Ingredient exposing (Ingredient)
import Data.Food.Query as Query exposing (Query)
import Data.Food.WellKnown as WellKnown exposing (WellKnown)
import Data.Impact as Impact
import Data.Process as Process exposing (Process)
import Data.Process exposing (Process)
import Json.Decode as Decode
import Result.Extra as RE


type alias Db =
{ examples : List (Example Query)
, ingredients : List Ingredient
, processes : List Process
, wellKnown : WellKnown
}


buildFromJson : String -> String -> String -> Result String Db
buildFromJson exampleProductsJson foodProcessesJson ingredientsJson =
foodProcessesJson
|> Decode.decodeString (Process.decodeList Impact.decodeImpacts)
|> Result.mapError Decode.errorToString
|> Result.andThen
(\processes ->
Ok Db
|> RE.andMap
(exampleProductsJson
|> Example.decodeListFromJsonString Query.decode
)
|> RE.andMap
(ingredientsJson
|> Decode.decodeString (Ingredient.decodeIngredients processes)
|> Result.mapError Decode.errorToString
)
|> RE.andMap (Ok processes)
|> RE.andMap (WellKnown.load processes)
buildFromJson : String -> String -> List Process -> Result String Db
buildFromJson exampleProductsJson ingredientsJson processes =
Ok Db
|> RE.andMap
(exampleProductsJson
|> Example.decodeListFromJsonString Query.decode
)
|> RE.andMap
(ingredientsJson
|> Decode.decodeString (Ingredient.decodeIngredients processes)
|> Result.mapError Decode.errorToString
)
|> RE.andMap (WellKnown.load processes)
14 changes: 5 additions & 9 deletions src/Data/Food/Recipe.elm
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ module Data.Food.Recipe exposing
)

import Data.Country as Country exposing (Country)
import Data.Food.Db as Food
import Data.Food.EcosystemicServices as EcosystemicServices exposing (EcosystemicServices)
import Data.Food.Ingredient as Ingredient exposing (Ingredient)
import Data.Food.Origin as Origin
Expand Down Expand Up @@ -457,9 +456,9 @@ fromQuery db query =
Ok Recipe
|> RE.andMap (Ok query.distribution)
|> RE.andMap (ingredientListFromQuery db query)
|> RE.andMap (packagingListFromQuery db.food query)
|> RE.andMap (packagingListFromQuery db query)
|> RE.andMap (preparationListFromQuery query)
|> RE.andMap (transformFromQuery db.food query)
|> RE.andMap (transformFromQuery db query)


getMassAtPackaging : Recipe -> Mass
Expand Down Expand Up @@ -604,16 +603,13 @@ ingredientQueryFromIngredient ingredient =
}


packagingListFromQuery :
Food.Db
-> { a | packaging : List BuilderQuery.ProcessQuery }
-> Result String (List Packaging)
packagingListFromQuery : Db -> { a | packaging : List BuilderQuery.ProcessQuery } -> Result String (List Packaging)
packagingListFromQuery db query =
query.packaging
|> RE.combineMap (packagingFromQuery db)


packagingFromQuery : Food.Db -> BuilderQuery.ProcessQuery -> Result String Packaging
packagingFromQuery : Db -> BuilderQuery.ProcessQuery -> Result String Packaging
packagingFromQuery { processes } { id, mass } =
processes
|> Process.findById id
Expand Down Expand Up @@ -684,7 +680,7 @@ toString { ingredients, packaging, transform } =


transformFromQuery :
Food.Db
Db
-> { a | transform : Maybe BuilderQuery.ProcessQuery }
-> Result String (Maybe Transform)
transformFromQuery { processes } query =
Expand Down
28 changes: 7 additions & 21 deletions src/Data/Object/Db.elm
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,20 @@ module Data.Object.Db exposing
, buildFromJson
)

import Data.Component as Component exposing (Component)
import Data.Example as Example exposing (Example)
import Data.Impact as Impact
import Data.Object.Query as Query exposing (Query)
import Data.Process as Process exposing (Process)
import Json.Decode as Decode
import Result.Extra as RE


type alias Db =
{ components : List Component
, examples : List (Example Query)
, processes : List Process
{ examples : List (Example Query)
}


buildFromJson : String -> String -> String -> Result String Db
buildFromJson objectComponentsJson objectExamplesJson objectProcessesJson =
objectProcessesJson
|> Decode.decodeString (Process.decodeList Impact.decodeImpacts)
|> Result.mapError Decode.errorToString
|> Result.andThen
(\processes ->
Ok Db
|> RE.andMap (Component.decodeListFromJsonString objectComponentsJson)
|> RE.andMap
(objectExamplesJson
|> Example.decodeListFromJsonString Query.decode
)
|> RE.andMap (Ok processes)
buildFromJson : String -> Result String Db
buildFromJson objectExamplesJson =
Ok Db
|> RE.andMap
(objectExamplesJson
|> Example.decodeListFromJsonString Query.decode
)
14 changes: 9 additions & 5 deletions src/Data/Process.elm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Data.Common.DecodeUtils as DU
import Data.Impact as Impact exposing (Impacts)
import Data.Impact.Definition as Definition
import Data.Process.Category as Category exposing (Category)
import Data.Scope as Scope exposing (Scope)
import Data.Split as Split exposing (Split)
import Data.Unit as Unit
import Data.Uuid as Uuid exposing (Uuid)
Expand Down Expand Up @@ -46,6 +47,7 @@ type alias Process =
, id : Id
, impacts : Impacts
, name : String
, scopes : List Scope
, source : String
, sourceId : Maybe SourceId
, unit : String
Expand Down Expand Up @@ -78,8 +80,8 @@ sourceIdToString (SourceId string) =
string


decodeProcess : Decoder Impact.Impacts -> Decoder Process
decodeProcess impactsDecoder =
decodeProcess : List Scope -> Decoder Impact.Impacts -> Decoder Process
decodeProcess scopes impactsDecoder =
Decode.succeed Process
|> Pipe.required "categories" Category.decodeList
|> Pipe.required "comment" Decode.string
Expand All @@ -90,6 +92,7 @@ decodeProcess impactsDecoder =
|> Pipe.required "id" decodeId
|> Pipe.required "impacts" impactsDecoder
|> Pipe.required "name" Decode.string
|> Pipe.hardcoded scopes
|> Pipe.required "source" Decode.string
|> DU.strictOptional "sourceId" decodeSourceId
|> Pipe.required "unit" Decode.string
Expand All @@ -108,6 +111,7 @@ encode process =
, ( "id", encodeId process.id )
, ( "impacts", Impact.encode process.impacts )
, ( "name", Encode.string process.name )
, ( "scopes", process.scopes |> Encode.list Scope.encode )
, ( "source", Encode.string process.source )
, ( "sourceId", EncodeExtra.maybe encodeSourceId process.sourceId )
, ( "unit", Encode.string process.unit )
Expand All @@ -126,9 +130,9 @@ decodeSourceId =
|> Decode.map sourceIdFromString


decodeList : Decoder Impact.Impacts -> Decoder (List Process)
decodeList =
decodeProcess >> Decode.list
decodeList : List Scope -> Decoder Impact.Impacts -> Decoder (List Process)
decodeList scopes =
decodeProcess scopes >> Decode.list


encodeId : Id -> Encode.Value
Expand Down
16 changes: 10 additions & 6 deletions src/Data/Scope.elm
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module Data.Scope exposing
( Scope(..)
, anyOf
, decode
, encode
, only
, parse
, toLabel
, toString
Expand All @@ -21,6 +21,15 @@ type Scope
| Veli


{-| Filter a list of scoped records against any passed allowed scopes
-}
anyOf : List Scope -> List { a | scopes : List Scope } -> List { a | scopes : List Scope }
anyOf scopes =
List.filter <|
.scopes
>> List.any (\scope -> List.member scope scopes)


decode : Decoder Scope
decode =
Decode.string
Expand Down Expand Up @@ -51,11 +60,6 @@ fromString string =
Err <| "Couldn't decode unknown scope " ++ string


only : Scope -> List { a | scopes : List Scope } -> List { a | scopes : List Scope }
only scope =
List.filter (.scopes >> List.member scope)


parse : Parser (Scope -> a) a
parse =
Parser.custom "SCOPE" <|
Expand Down
50 changes: 19 additions & 31 deletions src/Data/Textile/Db.elm
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ module Data.Textile.Db exposing
, buildFromJson
)

import Data.Component as Component exposing (Component)
import Data.Example as Example exposing (Example)
import Data.Impact as Impact
import Data.Process as Process exposing (Process)
import Data.Process exposing (Process)
import Data.Textile.Material as Material exposing (Material)
import Data.Textile.Product as Product exposing (Product)
import Data.Textile.Query as Query exposing (Query)
Expand All @@ -16,38 +14,28 @@ import Result.Extra as RE


type alias Db =
{ components : List Component
, examples : List (Example Query)
{ examples : List (Example Query)
, materials : List Material
, processes : List Process
, products : List Product
, wellKnown : WellKnown
}


buildFromJson : String -> String -> String -> String -> String -> Result String Db
buildFromJson textileComponentsJson exampleProductsJson materialsJson productsJson processesJson =
processesJson
|> Decode.decodeString (Process.decodeList Impact.decodeImpacts)
|> Result.mapError Decode.errorToString
|> Result.andThen
(\processes ->
Ok Db
|> RE.andMap (Component.decodeListFromJsonString textileComponentsJson)
|> RE.andMap
(exampleProductsJson
|> Example.decodeListFromJsonString Query.decode
)
|> RE.andMap
(materialsJson
|> Decode.decodeString (Material.decodeList processes)
|> Result.mapError Decode.errorToString
)
|> RE.andMap (Ok processes)
|> RE.andMap
(productsJson
|> Decode.decodeString (Product.decodeList processes)
|> Result.mapError Decode.errorToString
)
|> RE.andMap (WellKnown.load processes)
buildFromJson : String -> String -> String -> List Process -> Result String Db
buildFromJson exampleProductsJson textileMaterialsJson productsJson processes =
Ok Db
|> RE.andMap
(exampleProductsJson
|> Example.decodeListFromJsonString Query.decode
)
|> RE.andMap
(textileMaterialsJson
|> Decode.decodeString (Material.decodeList processes)
|> Result.mapError Decode.errorToString
)
|> RE.andMap
(productsJson
|> Decode.decodeString (Product.decodeList processes)
|> Result.mapError Decode.errorToString
)
|> RE.andMap (WellKnown.load processes)
Loading

0 comments on commit 02a9793

Please sign in to comment.