diff options
-rw-r--r-- | gen/any.erl | 28 | ||||
-rw-r--r-- | gen/result.erl | 14 | ||||
-rw-r--r-- | src/any.gleam | 120 | ||||
-rw-r--r-- | src/result.gleam | 12 |
4 files changed, 94 insertions, 80 deletions
diff --git a/gen/any.erl b/gen/any.erl index a29ed3d..951fab9 100644 --- a/gen/any.erl +++ b/gen/any.erl @@ -2,7 +2,7 @@ -compile(no_auto_import). -include_lib("eunit/include/eunit.hrl"). --export([from/1, unsafeCoerce/1, string/1, int/1, float/1, bool/1, thunk/1, tuple/1]). +-export([from/1, unsafeCoerce/1, string/1, int/1, float/1, bool/1, thunk/1, tuple/1, field/2]). from(A) -> gleam__stdlib:identity(A). @@ -66,5 +66,29 @@ tuple_test() -> expect:equal(tuple(from({<<"ok">>, <<"ok">>})), {ok, {from(<<"ok">>), from(<<"ok">>)}}), expect:is_error(tuple(from({1}))), - expect:is_error(tuple(from({1, 2, 3}))). + expect:is_error(tuple(from({1, 2, 3}))), + expect:equal(result:then(result:then(tuple(from({1, 2.0})), + fun(X) -> {A, B} = X, + result:map(int(A), + fun(I) -> + {I, B} + end) end), + fun(X) -> {A1, B1} = X, + result:map(float(B1), + fun(F) -> {A1, F} end) end), + {ok, {1, 2.0}}). +-endif. + +field(A, B) -> + gleam__stdlib:decode_field(A, B). + +-ifdef(TEST). +field_test() -> + {ok, OkAtom} = atom:from_string(<<"ok">>), + expect:equal(field(from(#{}#{ok => 1}), OkAtom), {ok, from(1)}), + expect:equal(field(from(#{}#{ok => 3}#{earlier => 2}), OkAtom), + {ok, from(3)}), + expect:is_error(field(from(#{}), OkAtom)), + expect:is_error(field(from(1), OkAtom)), + expect:is_error(field(from([]), [])). -endif. diff --git a/gen/result.erl b/gen/result.erl index 19d87ed..e793c6b 100644 --- a/gen/result.erl +++ b/gen/result.erl @@ -85,22 +85,18 @@ flatten_test() -> then(Result, Fun) -> case Result of {ok, X} -> - case Fun(X) of - {ok, Y} -> - {ok, Y}; + Fun(X); - {error, Y1} -> - {error, Y1} - end; - - {error, _} -> - Result + {error, E} -> + {error, E} end. -ifdef(TEST). then_test() -> expect:equal(then({error, 1}, fun(X) -> {ok, X + 1} end), {error, 1}), expect:equal(then({ok, 1}, fun(X) -> {ok, X + 1} end), {ok, 2}), + expect:equal(then({ok, 1}, fun(_) -> {ok, <<"type change">>} end), + {ok, <<"type change">>}), expect:equal(then({ok, 1}, fun(_) -> {error, 1} end), {error, 1}). -endif. diff --git a/src/any.gleam b/src/any.gleam index 41abed3..22dd0d5 100644 --- a/src/any.gleam +++ b/src/any.gleam @@ -1,4 +1,5 @@ import list +import atom import result import expect @@ -230,74 +231,67 @@ pub external fn tuple(Any) -> Result({Any, Any}, String) test tuple { {1, []} - |> from - |> tuple - |> expect:equal(_, Ok({from(1), from([])})) + |> from + |> tuple + |> expect:equal(_, Ok({from(1), from([])})) {"ok", "ok"} - |> from - |> tuple - |> expect:equal(_, Ok({from("ok"), from("ok")})) + |> from + |> tuple + |> expect:equal(_, Ok({from("ok"), from("ok")})) {1} - |> from - |> tuple - |> expect:is_error + |> from + |> tuple + |> expect:is_error {1, 2, 3} - |> from - |> tuple - |> expect:is_error - -// {1, 2.0} -// |> from -// |> tuple -// |> result:map(_, fn(x) { -// let {a, b} = x -// a |> int |> result:map(_, fn(x) { {x, b} }) -// }) -// // |> result:then(_, fn(x) { -// // let {a, b} = x -// // b |> float |> result:map(_, fn(x) { {a, x} }) -// // }) -// // |> expect:equal(_, Ok({1, 2.0})) + |> from + |> tuple + |> expect:is_error + + {1, 2.0} + |> from + |> tuple + |> result:then(_, fn(x) { + let {a, b} = x + a |> int |> result:map(_, fn(i) { {i, b} }) + }) + |> result:then(_, fn(x) { + let {a, b} = x + b |> float |> result:map(_, fn(f) { {a, f} }) + }) + |> expect:equal(_, Ok({1, 2.0})) } -////// TODO: FIXME: This doesn't work anymore because atoms are no longer a thing. -////// "Decode a field from a map, extracting a specified field. -////// -////// Multiple fields can be extracted and stored in a new record like so: -////// -////// Ok(name) <- decode:field(raw_data, \"name\") |> result:then(_, decode:string) -////// Ok(size) <- decode:field(raw_data, \"size\") |> result:then(_, decode:int) -////// Ok({ name = name, size = size }) -////// -////pub external fn field(Any, a) -> Result(String, Any) -//// = "gleam__stdlib" "field" - -////test field { -//// let _ = {ok = 1} -//// |> from -//// |> field("ok") -//// |> expect:equal(from(1)) - -//// let _ = {earlier = 2, ok = 3} -//// |> from -//// |> field("ok") -//// |> expect:equal(from(3)) - -//// let _ = {} -//// |> from -//// |> field("ok") -//// |> expect:is_error - -//// let _ = 1 -//// |> from -//// |> field("ok") -//// |> expect:is_error - -//// [] -//// |> from -//// |> field("ok") -//// |> expect:is_error -////} +pub external fn field(Any, a) -> Result(Any, String) + = "gleam__stdlib" "decode_field" + +test field { + let Ok(ok_atom) = atom:from_string("ok") + + {ok = 1} + |> from + |> field(_, ok_atom) + |> expect:equal(_, Ok(from(1))) + + {earlier = 2, ok = 3} + |> from + |> field(_, ok_atom) + |> expect:equal(_, Ok(from(3))) + + {} + |> from + |> field(_, ok_atom) + |> expect:is_error + + 1 + |> from + |> field(_, ok_atom) + |> expect:is_error + + [] + |> from + |> field(_, []) + |> expect:is_error +} diff --git a/src/result.gleam b/src/result.gleam index 18503ec..a2bd330 100644 --- a/src/result.gleam +++ b/src/result.gleam @@ -91,12 +91,8 @@ test flatten { pub fn then(result, fun) { case result { - | Ok(x) -> - case fun(x) { - | Ok(y) -> Ok(y) - | Error(y) -> Error(y) - } - | Error(_) -> result + | Ok(x) -> fun(x) + | Error(e) -> Error(e) } } @@ -110,6 +106,10 @@ test then { |> expect:equal(_, Ok(2)) Ok(1) + |> then(_, fn(_) { Ok("type change") }) + |> expect:equal(_, Ok("type change")) + + Ok(1) |> then(_, fn(_) { Error(1) }) |> expect:equal(_, Error(1)) } |