-
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.
(data) Cookbook deserialise and post-process YAML recipes (#2372)
* Deserialise and post-process recipes * add missing verb, other minor line editing * verb agreement, other line editing * fixed missed verb agreement & typo * editing --------- Co-authored-by: Cuihtlauac ALVARADO <[email protected]> Co-authored-by: Christine Rose <[email protected]> Co-authored-by: sabine <[email protected]>
- Loading branch information
1 parent
c4180a1
commit 800ea86
Showing
3 changed files
with
161 additions
and
0 deletions.
There are no files selected for viewing
78 changes: 78 additions & 0 deletions
78
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,78 @@ | ||
--- | ||
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 | ||
--- | ||
|
||
(* This YAML string contains a list of ingredients where the ingredients are represented as | ||
a YAML object, with keys representing names and values representing amounts. *) | ||
let yaml_string = {| | ||
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 the `ppx_deriving_yaml` library generate the function | ||
``ingredient_of_yaml : Yaml.value -> (ingredient, [> `Msg of string]) result``. *) | ||
type ingredient = { | ||
name: string; | ||
weight: int; | ||
} [@@deriving of_yaml] | ||
|
||
(* The `[@@deriving of_yaml]` attribute makes the `ppx_deriving_yaml` library 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] | ||
|
||
(* Since the structure of the YAML file does not exactly match the `recipe` type, | ||
we (1) parse the YAML file to the internal representation `Yaml.value` of the `yaml` package, | ||
and then (2) change the structure to match the `recipe` type, so we can use the `recipe_of_yaml` | ||
function. | ||
The functions `add_keys` and `at_ingredients` perform this post-processing. *) | ||
let add_keys = function | ||
| `O [(name, `Float weight)] -> | ||
`O [ | ||
("name", `String name); | ||
("weight", `Float weight); | ||
] | ||
| v -> v | ||
|
||
let at_ingredients f = 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 | ||
|
||
(* Parse, post-process, and convert the YAML string into an OCaml value of type `recipe`. *) | ||
let pate_sucree = | ||
yaml_string | ||
|> Yaml.of_string | ||
|> Result.map (at_ingredients add_keys) | ||
|> fun yaml -> Result.bind yaml recipe_of_yaml | ||
|
79 changes: 79 additions & 0 deletions
79
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,79 @@ | ||
--- | ||
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 | ||
--- | ||
|
||
(* This YAML string contains a list of ingredients where the ingredients are represented as | ||
a YAML object, with keys representing names and values representing amounts. *) | ||
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 the `ppx_deriving_yojson` library generate the function | ||
`ingredient_of_yojson : Yojson.Safe.t -> (ingredient, string) result`. *) | ||
type ingredient = { | ||
name: string; | ||
weight: int; | ||
} [@@deriving of_yojson] | ||
|
||
(* The `[@@deriving of_yojson]` attribute makes the `ppx_deriving_yojson` library 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] | ||
|
||
(* Since the structure of the YAML file does not exactly match the `recipe` type, | ||
we (1) parse the YAML file to the representation `Yojson.Safe.t`, | ||
and then (2) modify the `Yojson.Safe.t` value to change the structure to match the `recipe` type, | ||
so we can use the `recipe_of_yojson` function. | ||
The functions `add_keys` and `at_ingredients` perform this post-processing. *) | ||
let add_keys = function | ||
| `Assoc [(name, `Int weight)] -> | ||
`Assoc [ | ||
("name", `String name); | ||
("weight", `Int weight); | ||
] | ||
| v -> v | ||
|
||
let at_ingredients f = 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 | ||
|
||
(* Parse, post-process, and convert the YAML string into an OCaml value of type `recipe`. *) | ||
let pate_sucree = | ||
let of_yojson json = | ||
json | ||
|> at_ingredients add_keys | ||
|> recipe_of_yojson in | ||
yaml | ||
|> Hl_yaml.Unix.parse ~of_yojson |
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