diff options
author | Louis Pilfold <louis@lpil.uk> | 2021-09-10 19:10:32 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-09-10 19:10:32 +0100 |
commit | 72889a32caa561ffe083a7c921f856c23c0ee5f6 (patch) | |
tree | 957f327e1b7f9ac99eed29ba1799ea460615549c | |
parent | 1d6a4b91d7db1cd7d5c66a9a0e5bc4be22e6099b (diff) | |
download | gleam_stdlib-72889a32caa561ffe083a7c921f856c23c0ee5f6.tar.gz gleam_stdlib-72889a32caa561ffe083a7c921f856c23c0ee5f6.zip |
JS result decoding
-rw-r--r-- | src/gleam/dynamic.gleam | 111 | ||||
-rw-r--r-- | src/gleam_stdlib.erl | 2 | ||||
-rw-r--r-- | src/gleam_stdlib.js | 13 | ||||
-rw-r--r-- | test/gleam/dynamic_test.gleam | 86 |
4 files changed, 112 insertions, 100 deletions
diff --git a/src/gleam/dynamic.gleam b/src/gleam/dynamic.gleam index 4cc71a4..726fbeb 100644 --- a/src/gleam/dynamic.gleam +++ b/src/gleam/dynamic.gleam @@ -243,60 +243,69 @@ if javascript { "../gleam_stdlib.js" "decode_list" } +/// Checks to see whether a Dynamic value is a result, and return the result if +/// it is. +/// +/// ## Examples +/// +/// > result(from(Ok(1))) +/// Ok(Ok(from(1))) +/// +/// > result(from(Error("boom"))) +/// Ok(Error(from("boom"))) +/// +/// > result(from(123)) +/// Error(DecodeError(expected: "2 element tuple", found: "Int")) +/// +pub fn result( + from value: Dynamic, +) -> Result(Result(Dynamic, Dynamic), DecodeError) { + decode_result(value) +} + if erlang { - /// Checks to see whether a Dynamic value is a result, and return the result if - /// it is. - /// - /// ## Examples - /// - /// > result(from(Ok(1))) - /// Ok(Ok(from(1))) - /// - /// > result(from(Error("boom"))) - /// Ok(Error(from("boom"))) - /// - /// > result(from(123)) - /// Error(DecodeError(expected: "2 element tuple", found: "Int")) - /// - pub external fn result( - Dynamic, - ) -> Result(Result(Dynamic, Dynamic), DecodeError) = + external fn decode_result(Dynamic) -> Result(Result(a, e), DecodeError) = "gleam_stdlib" "decode_result" +} - /// Checks to see whether a Dynamic value is a result of a particular type, and - /// return the result if it is - /// - /// The `ok` and `error` arguments are decoders for decoding the `Ok` and - /// `Error` values of the result. - /// - /// ## Examples - /// - /// > typed_result(of: from(Ok(1)), ok: int, error: string) - /// Ok(Ok(1)) - /// - /// > typed_result(of: from(Error("boom")), ok: int, error: string) - /// Ok(Error("boom")) - /// - /// > typed_result(of: from(123), ok: int, error: string) - /// Error(DecodeError(expected: "2 element tuple", found: "Int")) - /// - pub fn typed_result( - of dynamic: Dynamic, - ok decode_ok: Decoder(a), - error decode_error: Decoder(e), - ) -> Result(Result(a, e), DecodeError) { - try inner_result = result(dynamic) - - case inner_result { - Ok(raw) -> - raw - |> decode_ok - |> result.map(Ok) - Error(raw) -> - raw - |> decode_error - |> result.map(Error) - } +if javascript { + external fn decode_result(Dynamic) -> Result(Result(a, e), DecodeError) = + "../gleam_stdlib.js" "decode_result" +} + +/// Checks to see whether a Dynamic value is a result of a particular type, and +/// return the result if it is +/// +/// The `ok` and `error` arguments are decoders for decoding the `Ok` and +/// `Error` values of the result. +/// +/// ## Examples +/// +/// > typed_result(of: from(Ok(1)), ok: int, error: string) +/// Ok(Ok(1)) +/// +/// > typed_result(of: from(Error("boom")), ok: int, error: string) +/// Ok(Error("boom")) +/// +/// > typed_result(of: from(123), ok: int, error: string) +/// Error(DecodeError(expected: "2 element tuple", found: "Int")) +/// +pub fn typed_result( + of dynamic: Dynamic, + ok decode_ok: Decoder(a), + error decode_error: Decoder(e), +) -> Result(Result(a, e), DecodeError) { + try inner_result = result(dynamic) + + case inner_result { + Ok(raw) -> + raw + |> decode_ok + |> result.map(Ok) + Error(raw) -> + raw + |> decode_error + |> result.map(Error) } } diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl index 72082d1..c901499 100644 --- a/src/gleam_stdlib.erl +++ b/src/gleam_stdlib.erl @@ -129,7 +129,7 @@ decode_result(Term) -> ok -> {ok, {ok, nil}}; {error, Inner} -> {ok, {error, Inner}}; error -> {ok, {error, nil}}; - _ -> decode_error_msg(<<"result tuple">>, Term) + _ -> decode_error_msg(<<"Result">>, Term) end. parse_int(String) -> diff --git a/src/gleam_stdlib.js b/src/gleam_stdlib.js index 4a3026c..4c52daf 100644 --- a/src/gleam_stdlib.js +++ b/src/gleam_stdlib.js @@ -1,12 +1,13 @@ import { - Ok, + BitString, Error, List, - BitString, + Ok, + Result, UtfCodepoint, - toBitString, - stringBits, inspect, + stringBits, + toBitString, } from "./gleam.js"; import { CompileError as RegexCompileError, @@ -532,6 +533,10 @@ export function decode_list(data) { return List.isList(data) ? new Ok(data) : decoder_error("List", data); } +export function decode_result(data) { + return Result.isResult(data) ? new Ok(data) : decoder_error("Result", data); +} + export function decode_map(data) { return data instanceof Map ? new Ok(data) : decoder_error("Map", data); } diff --git a/test/gleam/dynamic_test.gleam b/test/gleam/dynamic_test.gleam index b901c86..2fb4a2a 100644 --- a/test/gleam/dynamic_test.gleam +++ b/test/gleam/dynamic_test.gleam @@ -752,56 +752,54 @@ pub fn list_test() { |> should.equal(Error(DecodeError(expected: "List", found: "Int"))) } -if erlang { - pub fn result_test() { - Ok(1) - |> dynamic.from - |> dynamic.result - |> should.equal(Ok(Ok(dynamic.from(1)))) +pub fn result_test() { + Ok(1) + |> dynamic.from + |> dynamic.result + |> should.equal(Ok(Ok(dynamic.from(1)))) - Error("error") - |> dynamic.from - |> dynamic.result - |> should.equal(Ok(Error(dynamic.from("error")))) + Error("error") + |> dynamic.from + |> dynamic.result + |> should.equal(Ok(Error(dynamic.from("error")))) - 1 - |> dynamic.from - |> dynamic.result - |> should.equal(Error(DecodeError(expected: "result tuple", found: "Int"))) + 1 + |> dynamic.from + |> dynamic.result + |> should.equal(Error(DecodeError(expected: "Result", found: "Int"))) - #("bad", "value") - |> dynamic.from - |> dynamic.result - |> should.equal(Error(DecodeError( - expected: "result tuple", - found: "Tuple of 2 elements", - ))) - } + #("bad", "value") + |> dynamic.from + |> dynamic.result + |> should.equal(Error(DecodeError( + expected: "Result", + found: "Tuple of 2 elements", + ))) +} - pub fn typed_result_test() { - Ok(1) - |> dynamic.from - |> dynamic.typed_result(ok: dynamic.int, error: dynamic.string) - |> should.equal(Ok(Ok(1))) +pub fn typed_result_test() { + Ok(1) + |> dynamic.from + |> dynamic.typed_result(ok: dynamic.int, error: dynamic.string) + |> should.equal(Ok(Ok(1))) - Error("error") - |> dynamic.from - |> dynamic.typed_result(ok: dynamic.int, error: dynamic.string) - |> should.equal(Ok(Error("error"))) + Error("error") + |> dynamic.from + |> dynamic.typed_result(ok: dynamic.int, error: dynamic.string) + |> should.equal(Ok(Error("error"))) - Ok("1") - |> dynamic.from - |> dynamic.typed_result(ok: dynamic.int, error: dynamic.string) - |> should.equal(Error(DecodeError(expected: "Int", found: "String"))) + Ok("1") + |> dynamic.from + |> dynamic.typed_result(ok: dynamic.int, error: dynamic.string) + |> should.equal(Error(DecodeError(expected: "Int", found: "String"))) - Error(1) - |> dynamic.from - |> dynamic.typed_result(ok: dynamic.int, error: dynamic.string) - |> should.equal(Error(DecodeError(expected: "String", found: "Int"))) + Error(1) + |> dynamic.from + |> dynamic.typed_result(ok: dynamic.int, error: dynamic.string) + |> should.equal(Error(DecodeError(expected: "String", found: "Int"))) - 1 - |> dynamic.from - |> dynamic.typed_result(ok: dynamic.int, error: dynamic.string) - |> should.equal(Error(DecodeError(expected: "result tuple", found: "Int"))) - } + 1 + |> dynamic.from + |> dynamic.typed_result(ok: dynamic.int, error: dynamic.string) + |> should.equal(Error(DecodeError(expected: "Result", found: "Int"))) } |