-
Notifications
You must be signed in to change notification settings - Fork 323
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Deserialise and post-process recipes
- Loading branch information
Cuihtlauac ALVARADO
committed
Apr 25, 2024
1 parent
bb8bf85
commit 9d4963f
Showing
2 changed files
with
145 additions
and
0 deletions.
There are no files selected for viewing
72 changes: 72 additions & 0 deletions
72
data/cookbook/deserialise-post-process-from-yaml/00-yaml.ml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
--- | ||
packages: | ||
- name: yaml | ||
tested_version: 3.2.0 | ||
used_libraries: | ||
- yaml | ||
- name: ppx_deriving_yaml | ||
tested_version: 0.2.2 | ||
used_libraries: | ||
- ppx_deriving_yaml | ||
--- | ||
(* The syntax `{| ... |}` is a quoted string. *) | ||
let yaml = {| | ||
french name: pâte sucrée | ||
ingredients: | ||
- flour: 250 | ||
- butter: 100 | ||
- sugar: 100 | ||
- egg: 50 | ||
- salt: 5 | ||
steps: | ||
- soften butter | ||
- add sugar | ||
- add egg and salt | ||
- add flour | ||
|} | ||
|
||
(* The `[@@deriving of_yaml]` attribute makes library `ppx_deriving_yaml` generate the function | ||
``ingredient_of_yaml : Yaml.value -> (ingredient, [> `Msg of string]) result`` | ||
If both serialising and deserialising are needed, replace `of_yaml` by `yaml`. *) | ||
type ingredient = { | ||
name: string; | ||
weight: int; | ||
} [@@deriving of_yaml] | ||
|
||
(* The `[@@deriving of_yaml]` attribute makes library `ppx_deriving_yaml` generate the function | ||
``recipe_of_yaml : Yaml.value -> (ingredient, [> `Msg of string]) result``. *) | ||
type recipe = { | ||
name: string; [@key "french name"] | ||
ingredients: ingredient list; | ||
steps: string list; | ||
} [@@deriving of_yaml] | ||
|
||
(* Post-processing is needed before using `recipe_of_yaml`. | ||
This what function `add_keys` and `at_ingredients` do. *) | ||
let add_keys : Yaml.value -> Yaml.value = function | ||
| `O [(name, `Float weight)] -> | ||
`O [ | ||
("name", `String name); | ||
("weight", `Float weight); | ||
] | ||
| v -> v | ||
|
||
let at_ingredients f : Yaml.value -> Yaml.value = function | ||
| `O [ | ||
("french name", `String name); | ||
("ingredients", `A ingredients); | ||
("steps", `A steps) | ||
] -> `O [ | ||
("french name", `String name); | ||
("ingredients", Yaml.Util.map_exn f (`A ingredients)); | ||
("steps", `A steps); | ||
] | ||
| v -> v | ||
|
||
(* Parsing, post-processing and conversion into recordd are chained. *) | ||
let pate_sucree = | ||
yaml | ||
|> Yaml.of_string | ||
|> Result.map (at_ingredients add_keys) | ||
|> fun yaml -> Result.bind yaml recipe_of_yaml | ||
|
73 changes: 73 additions & 0 deletions
73
data/cookbook/deserialise-post-process-from-yaml/01-hl_yaml.ml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
--- | ||
packages: | ||
- name: hl_yaml | ||
tested_version: 1.0.0 | ||
used_libraries: | ||
- hl_yaml | ||
- name: ppx_deriving_yojson | ||
tested_version: 3.7.0 | ||
used_libraries: | ||
- ppx_deriving_yojson | ||
--- | ||
(* The syntax `{| ... |}` is a quoted string. *) | ||
let yaml = {| | ||
french name: pâte sucrée | ||
ingredients: | ||
- flour: 250 | ||
- butter: 100 | ||
- sugar: 100 | ||
- egg: 50 | ||
- salt: 5 | ||
steps: | ||
- soften butter | ||
- add sugar | ||
- add egg and salt | ||
- add flour | ||
|} | ||
|
||
(* The `[@@deriving of_yojson]` attribute makes library `ppx_deriving_yojson` generate the function | ||
`ingredient_of_yojson : Yojson.Safe.t -> (ingredient, string) result`. | ||
If both serialising and deserialising are needed, replace `of_yojson` by `yojson`. *) | ||
type ingredient = { | ||
name: string; | ||
weight: int; | ||
} [@@deriving of_yojson] | ||
|
||
(* The `[@@deriving of_yojson]` attribute makes library `ppx_deriving_yojson` generate the function | ||
``recipe_of_yojson : Yojson.Safe.t -> (ingredient, string) result``. *) | ||
type recipe = { | ||
name: string; [@key "french name"] | ||
ingredients: ingredient list; | ||
steps: string list; | ||
} [@@deriving of_yojson] | ||
|
||
(* Post-processing is needed before using `recipe_of_yojson`. | ||
This what function `add_keys` and `at_ingredients` do. *) | ||
let add_keys : Yojson.Safe.t -> Yojson.Safe.t = function | ||
| `Assoc [(name, `Int weight)] -> | ||
`Assoc [ | ||
("name", `String name); | ||
("weight", `Int weight); | ||
] | ||
| v -> v | ||
|
||
let at_ingredients f : Yojson.Safe.t -> Yojson.Safe.t = function | ||
| `Assoc [ | ||
("french name", `String name); | ||
("ingredients", `List ingredients); | ||
("steps", `List steps) | ||
] -> `Assoc [ | ||
("french name", `String name); | ||
("ingredients", Yojson.Safe.Util.map f (`List ingredients)); | ||
("steps", `List steps); | ||
] | ||
| v -> v | ||
|
||
(* Parsing receives post-processing and conversion into record as an argument. *) | ||
let pate_sucree = | ||
let of_yojson json = | ||
json | ||
|> at_ingredients add_keys | ||
|> recipe_of_yojson in | ||
yaml | ||
|> Hl_yaml.Unix.parse ~of_yojson |