diff options
author | sharno <sharnoby3@gmail.com> | 2020-10-26 22:01:48 -0400 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2020-10-27 15:14:56 +0100 |
commit | cbdd74a5e78a85be8d4d49a93b87e501e5b0aef5 (patch) | |
tree | 1837f4b1763ec8b712832ac13db5297b1d655e2b /src | |
parent | 5239830bc8bf6d8c1df566e7bfe995ff24d8514a (diff) | |
download | gleam_stdlib-cbdd74a5e78a85be8d4d49a93b87e501e5b0aef5.tar.gz gleam_stdlib-cbdd74a5e78a85be8d4d49a93b87e501e5b0aef5.zip |
Closes #115: Add dynamic.option
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/dynamic.gleam | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam index bf7963f..e4656c4 100644 --- a/src/gleam/dynamic.gleam +++ b/src/gleam/dynamic.gleam @@ -1,8 +1,9 @@ import gleam/bit_string.{BitString} as bit_string_mod import gleam/list as list_mod -import gleam/atom +import gleam/atom as atom_mod import gleam/map.{Map} import gleam/result +import gleam/option.{None, Option, Some} /// `Dynamic` data is data that we don"t know the type of yet. /// We likely get data like this from interop with Erlang, or from @@ -102,7 +103,7 @@ pub external fn float(from: Dynamic) -> Result(Float, String) = /// > atom(from(123)) /// Error("Expected an Atom, got `123`") /// -pub external fn atom(from: Dynamic) -> Result(atom.Atom, String) = +pub external fn atom(from: Dynamic) -> Result(atom_mod.Atom, String) = "gleam_stdlib" "decode_atom" /// Check to see whether a Dynamic value is an bool, and return the bool if @@ -182,6 +183,36 @@ pub fn typed_list( |> result.then(list_mod.try_map(_, decoder_type)) } +/// Check to see if a Dynamic value is an Option of a particular type, and return +/// the Option if it is. +/// +/// The second argument is a decoder function used to decode the elements of +/// the list. The list is only decoded if all elements in the list can be +/// successfully decoded using this function. +/// +/// ## Examples +/// +/// > option(from("Hello"), string) +/// Ok(Some("Hello")) +/// +/// > option(from(atom.from_string("null")), string) +/// Ok(None) +/// +/// > option(from(123), string) +/// Error("Expected a bit_string, got an int") +/// +pub fn option( + from dynamic: Dynamic, + of decoder: Decoder(inner), +) -> Result(Option(inner), String) { + let Ok(null) = atom_mod.from_string("null") + case atom(dynamic), decoder(dynamic) { + Ok(atom), _ if atom == null -> Ok(None) + _, Ok(result) -> Ok(Some(result)) + _, Error(msg) -> Error(msg) + } +} + /// Check to see if a Dynamic value is a map with a specific field, and return /// the value of the field if it is. /// |