diff options
author | Giacomo Cavalieri <giacomo.cavalieri@icloud.com> | 2023-04-21 16:58:57 +0200 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2023-04-29 14:33:18 +0100 |
commit | f8ec25ccc7d4e3735268ec05906836922b14172f (patch) | |
tree | 7d51a2dd7b6fc2c9738f2d521032923ec62906d2 /src | |
parent | 54b22b142d17f0fd893ec2465e53b92109aadb48 (diff) | |
download | gleam_stdlib-f8ec25ccc7d4e3735268ec05906836922b14172f.tar.gz gleam_stdlib-f8ec25ccc7d4e3735268ec05906836922b14172f.zip |
`optional_field` implementation
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/dynamic.gleam | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam index 4f0708f..68000dd 100644 --- a/src/gleam/dynamic.gleam +++ b/src/gleam/dynamic.gleam @@ -484,6 +484,54 @@ pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { } } +/// Checks to see if a `Dynamic` value is a map with a specific field. +/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, +/// returns the decoded field wrapped in `Some(_)`. +/// +/// ## Examples +/// +/// ```gleam +/// > import gleam/map +/// > map.new() +/// > |> map.insert("Hello", "World") +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok(Some("World")) +/// ``` +/// +/// ```gleam +/// > import gleam/map +/// > map.new() +/// > |> from +/// > |> field(named: "Hello", of: string) +/// Ok(None) +/// ``` +/// +/// ```gleam +/// > from(123) +/// > |> field("Hello", string) +/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) +/// ``` +/// +pub fn optional_field( + named name: a, + of inner_type: Decoder(t), +) -> Decoder(Option(t)) { + fn(value) { + case decode_field(value, name) { + Error(not_a_map_errors) -> Error(not_a_map_errors) + Ok(dynamic_field_result) -> + case dynamic_field_result { + Error(_) -> Ok(option.None) + Ok(dynamic_field) -> + dynamic_field + |> decode_optional(inner_type) + |> map_errors(push_path(_, name)) + } + } + } +} + if erlang { external fn decode_field( Dynamic, |