-module(decode). -compile(no_auto_import). -export([bool/0, atom/0, int/0, float/0, string/0, element/2, field/2, atom_field/2, list/1, dynamic/0, succeed/1, fail/1, one_of/1, then/2, from_result/1, ok_error_tuple/2, map/2, map2/3, map3/4, map4/5, map5/6, map6/7, map7/8, map8/9, decode_dynamic/2]). bool() -> {decoder, fun gleam@dynamic:bool/1}. atom() -> {decoder, fun gleam@dynamic:atom/1}. int() -> {decoder, fun gleam@dynamic:int/1}. float() -> {decoder, fun gleam@dynamic:float/1}. string() -> {decoder, fun gleam@dynamic:string/1}. element(Position, Decoder) -> {decoder, DecodeFun} = Decoder, Fun = fun(Dynamic) -> gleam@result:then(gleam@dynamic:element(Dynamic, Position), DecodeFun) end, {decoder, Fun}. field(Named, Decoder) -> {decoder, DecodeFun} = Decoder, Fun = fun(Dynamic) -> gleam@result:then(gleam@dynamic:field(Dynamic, Named), DecodeFun) end, {decoder, Fun}. atom_field(Named, Decoder) -> {decoder, DecodeFun} = Decoder, NamedResult = gleam@result:map_error( gleam@atom:from_string(Named), fun(_) -> gleam@string:append( gleam@string:append(<<"No atom key by name of `">>, Named), <<"` found">> ) end ), Fun = fun(Dynamic) -> gleam@result:then( gleam@result:then( NamedResult, fun(Capture1) -> gleam@dynamic:field(Dynamic, Capture1) end ), DecodeFun ) end, {decoder, Fun}. list(Decoder) -> {decoder, DecodeFun} = Decoder, ListFun = fun(Dynamic) -> gleam@dynamic:list(Dynamic, DecodeFun) end, {decoder, ListFun}. dynamic() -> {decoder, fun(Dynamic) -> {ok, Dynamic} end}. succeed(A) -> {decoder, fun(_) -> {ok, A} end}. fail(Error) -> {decoder, fun(_) -> {error, Error} end}. try_decoders(Dynamic, Decoders) -> case Decoders of [{decoder, DecodeFun} | RemainingDecoders] -> case DecodeFun(Dynamic) of {ok, Val} -> {ok, Val}; {error, _} -> try_decoders(Dynamic, RemainingDecoders) end; [] -> {error, <<"All decoders failed">>} end. one_of(Decoders) -> {decoder, fun(Dynamic) -> try_decoders(Dynamic, Decoders) end}. compose(FirstFun, SecondFun) -> fun(A) -> SecondFun(FirstFun(A)) end. unwrap(Decoder) -> {decoder, DecodeFun} = Decoder, DecodeFun. then(Decoder, Fun) -> {decoder, DecodeFun} = Decoder, UnwrappedDecoderFun = compose(Fun, fun unwrap/1), {decoder, fun(Dynamic) -> gleam@result:then( DecodeFun(Dynamic), fun(A) -> (UnwrappedDecoderFun(A))(Dynamic) end ) end}. from_result(Result) -> case Result of {ok, Value} -> succeed(Value); {error, Error} -> fail(Error) end. ok_error_tuple(OkDecoder, ErrorDecoder) -> FailureDecoder = fun(AtomAsString) -> fail( gleam@string:append( gleam@string:append( <<"Expected 'ok' or 'error' atom in first position of tuple, got '">>, AtomAsString ), <<"' atom instead">> ) ) end, SuccessOrFailureFun = fun(ResultAtom) -> case gleam@atom:to_string(ResultAtom) of <<"ok">> -> OkDecoder; <<"error">> -> ErrorDecoder; AtomAsString1 -> FailureDecoder(AtomAsString1) end end, then(element(0, atom()), SuccessOrFailureFun). map(Fun, Decoder) -> {decoder, DecodeFun} = Decoder, MappedFun = fun(Dynamic) -> gleam@result:map(DecodeFun(Dynamic), Fun) end, {decoder, MappedFun}. map2(Fun, Decoder1, Decoder2) -> {decoder, DecodeFun1} = Decoder1, {decoder, DecodeFun2} = Decoder2, MappedFun = fun(Dynamic) -> case {DecodeFun1(Dynamic), DecodeFun2(Dynamic)} of {{ok, A}, {ok, B}} -> {ok, Fun(A, B)}; {{error, Str}, _} -> {error, Str}; {_, {error, Str}} -> {error, Str} end end, {decoder, MappedFun}. map3(Fun, Decoder1, Decoder2, Decoder3) -> {decoder, DecodeFun1} = Decoder1, {decoder, DecodeFun2} = Decoder2, {decoder, DecodeFun3} = Decoder3, MappedFun = fun(Dynamic) -> case {DecodeFun1(Dynamic), DecodeFun2(Dynamic), DecodeFun3(Dynamic)} of {{ok, A}, {ok, B}, {ok, C}} -> {ok, Fun(A, B, C)}; {{error, Str}, _, _} -> {error, Str}; {_, {error, Str}, _} -> {error, Str}; {_, _, {error, Str}} -> {error, Str} end end, {decoder, MappedFun}. map4(Fun, Decoder1, Decoder2, Decoder3, Decoder4) -> {decoder, DecodeFun1} = Decoder1, {decoder, DecodeFun2} = Decoder2, {decoder, DecodeFun3} = Decoder3, {decoder, DecodeFun4} = Decoder4, MappedFun = fun(Dynamic) -> case {DecodeFun1(Dynamic), DecodeFun2(Dynamic), DecodeFun3(Dynamic), DecodeFun4(Dynamic)} of {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> {ok, Fun(A, B, C, D)}; {{error, Str}, _, _, _} -> {error, Str}; {_, {error, Str}, _, _} -> {error, Str}; {_, _, {error, Str}, _} -> {error, Str}; {_, _, _, {error, Str}} -> {error, Str} end end, {decoder, MappedFun}. map5(Fun, Decoder1, Decoder2, Decoder3, Decoder4, Decoder5) -> {decoder, DecodeFun1} = Decoder1, {decoder, DecodeFun2} = Decoder2, {decoder, DecodeFun3} = Decoder3, {decoder, DecodeFun4} = Decoder4, {decoder, DecodeFun5} = Decoder5, MappedFun = fun(Dynamic) -> case {DecodeFun1(Dynamic), DecodeFun2(Dynamic), DecodeFun3(Dynamic), DecodeFun4(Dynamic), DecodeFun5(Dynamic)} of {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> {ok, Fun(A, B, C, D, E)}; {{error, Str}, _, _, _, _} -> {error, Str}; {_, {error, Str}, _, _, _} -> {error, Str}; {_, _, {error, Str}, _, _} -> {error, Str}; {_, _, _, {error, Str}, _} -> {error, Str}; {_, _, _, _, {error, Str}} -> {error, Str} end end, {decoder, MappedFun}. map6(Fun, Decoder1, Decoder2, Decoder3, Decoder4, Decoder5, Decoder6) -> {decoder, DecodeFun1} = Decoder1, {decoder, DecodeFun2} = Decoder2, {decoder, DecodeFun3} = Decoder3, {decoder, DecodeFun4} = Decoder4, {decoder, DecodeFun5} = Decoder5, {decoder, DecodeFun6} = Decoder6, MappedFun = fun(Dynamic) -> case {DecodeFun1(Dynamic), DecodeFun2(Dynamic), DecodeFun3(Dynamic), DecodeFun4(Dynamic), DecodeFun5(Dynamic), DecodeFun6(Dynamic)} of {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> {ok, Fun(A, B, C, D, E, F)}; {{error, Str}, _, _, _, _, _} -> {error, Str}; {_, {error, Str}, _, _, _, _} -> {error, Str}; {_, _, {error, Str}, _, _, _} -> {error, Str}; {_, _, _, {error, Str}, _, _} -> {error, Str}; {_, _, _, _, {error, Str}, _} -> {error, Str}; {_, _, _, _, _, {error, Str}} -> {error, Str} end end, {decoder, MappedFun}. map7( Fun, Decoder1, Decoder2, Decoder3, Decoder4, Decoder5, Decoder6, Decoder7 ) -> {decoder, DecodeFun1} = Decoder1, {decoder, DecodeFun2} = Decoder2, {decoder, DecodeFun3} = Decoder3, {decoder, DecodeFun4} = Decoder4, {decoder, DecodeFun5} = Decoder5, {decoder, DecodeFun6} = Decoder6, {decoder, DecodeFun7} = Decoder7, MappedFun = fun(Dynamic) -> case {DecodeFun1(Dynamic), DecodeFun2(Dynamic), DecodeFun3(Dynamic), DecodeFun4(Dynamic), DecodeFun5(Dynamic), DecodeFun6(Dynamic), DecodeFun7(Dynamic)} of {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> {ok, Fun(A, B, C, D, E, F, G)}; {{error, Str}, _, _, _, _, _, _} -> {error, Str}; {_, {error, Str}, _, _, _, _, _} -> {error, Str}; {_, _, {error, Str}, _, _, _, _} -> {error, Str}; {_, _, _, {error, Str}, _, _, _} -> {error, Str}; {_, _, _, _, {error, Str}, _, _} -> {error, Str}; {_, _, _, _, _, {error, Str}, _} -> {error, Str}; {_, _, _, _, _, _, {error, Str}} -> {error, Str} end end, {decoder, MappedFun}. map8( Fun, Decoder1, Decoder2, Decoder3, Decoder4, Decoder5, Decoder6, Decoder7, Decoder8 ) -> {decoder, DecodeFun1} = Decoder1, {decoder, DecodeFun2} = Decoder2, {decoder, DecodeFun3} = Decoder3, {decoder, DecodeFun4} = Decoder4, {decoder, DecodeFun5} = Decoder5, {decoder, DecodeFun6} = Decoder6, {decoder, DecodeFun7} = Decoder7, {decoder, DecodeFun8} = Decoder8, MappedFun = fun(Dynamic) -> case {DecodeFun1(Dynamic), DecodeFun2(Dynamic), DecodeFun3(Dynamic), DecodeFun4(Dynamic), DecodeFun5(Dynamic), DecodeFun6(Dynamic), DecodeFun7(Dynamic), DecodeFun8(Dynamic)} of {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}, {ok, H}} -> {ok, Fun(A, B, C, D, E, F, G, H)}; {{error, Str}, _, _, _, _, _, _, _} -> {error, Str}; {_, {error, Str}, _, _, _, _, _, _} -> {error, Str}; {_, _, {error, Str}, _, _, _, _, _} -> {error, Str}; {_, _, _, {error, Str}, _, _, _, _} -> {error, Str}; {_, _, _, _, {error, Str}, _, _, _} -> {error, Str}; {_, _, _, _, _, {error, Str}, _, _} -> {error, Str}; {_, _, _, _, _, _, {error, Str}, _} -> {error, Str}; {_, _, _, _, _, _, _, {error, Str}} -> {error, Str} end end, {decoder, MappedFun}. decode_dynamic(Dynamic, Decoder) -> {decoder, DecodeFun} = Decoder, DecodeFun(Dynamic).