-module(bison@ejson@decoder). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). -export([from_canonical/1]). -spec int(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. int(Dyn) -> (gleam@dynamic:decode1( fun(Field@0) -> {int32, Field@0} end, fun gleam@dynamic:int/1 ))(Dyn). -spec double(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. double(Dyn) -> (gleam@dynamic:decode1( fun(Field@0) -> {double, Field@0} end, fun gleam@dynamic:float/1 ))(Dyn). -spec bool(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. bool(Dyn) -> (gleam@dynamic:decode1( fun(Field@0) -> {boolean, Field@0} end, fun gleam@dynamic:bool/1 ))(Dyn). -spec string(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. string(Dyn) -> (gleam@dynamic:decode1( fun(Field@0) -> {string, Field@0} end, fun gleam@dynamic:string/1 ))(Dyn). -spec code(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. code(Dyn) -> (gleam@dynamic:decode1( fun(Field@0) -> {js, Field@0} end, gleam@dynamic:field(<<"$code"/utf8>>, fun gleam@dynamic:string/1) ))(Dyn). -spec oid(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. oid(Dyn) -> (gleam@dynamic:decode1( fun(Field@0) -> {object_id, Field@0} end, gleam@dynamic:field(<<"$oid"/utf8>>, fun(V) -> _pipe = V, _pipe@1 = gleam@dynamic:string(_pipe), _pipe@3 = gleam@result:map( _pipe@1, fun(S) -> _pipe@2 = bison@object_id:from_string(S), gleam@result:replace_error( _pipe@2, [{decode_error, <<"object id"/utf8>>, <<"not object id"/utf8>>, []}] ) end ), gleam@result:flatten(_pipe@3) end) ))(Dyn). -spec min(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. min(Dyn) -> _pipe = Dyn, _pipe@1 = (gleam@dynamic:field(<<"$minKey"/utf8>>, fun gleam@dynamic:int/1))( _pipe ), _pipe@2 = gleam@result:map(_pipe@1, fun(S) -> case S of 1 -> {ok, min}; _ -> {error, [{decode_error, <<"1"/utf8>>, gleam@int:to_string(S), []}]} end end), gleam@result:flatten(_pipe@2). -spec max(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. max(Dyn) -> _pipe = Dyn, _pipe@1 = (gleam@dynamic:field(<<"$maxKey"/utf8>>, fun gleam@dynamic:int/1))( _pipe ), _pipe@2 = gleam@result:map(_pipe@1, fun(S) -> case S of 1 -> {ok, max}; _ -> {error, [{decode_error, <<"1"/utf8>>, gleam@int:to_string(S), []}]} end end), gleam@result:flatten(_pipe@2). -spec typed_int(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. typed_int(Dyn) -> _pipe = Dyn, _pipe@1 = (gleam@dynamic:field( <<"$numberInt"/utf8>>, fun gleam@dynamic:string/1 ))(_pipe), _pipe@2 = gleam@result:map(_pipe@1, fun(S) -> case gleam@int:parse(S) of {ok, N} -> {ok, {int32, N}}; _ -> {error, [{decode_error, <<"Integer"/utf8>>, S, []}]} end end), gleam@result:flatten(_pipe@2). -spec typed_long(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. typed_long(Dyn) -> _pipe = Dyn, _pipe@1 = (gleam@dynamic:field( <<"$numberLong"/utf8>>, fun gleam@dynamic:string/1 ))(_pipe), _pipe@2 = gleam@result:map(_pipe@1, fun(S) -> case gleam@int:parse(S) of {ok, N} -> {ok, {int64, N}}; _ -> {error, [{decode_error, <<"Integer"/utf8>>, S, []}]} end end), gleam@result:flatten(_pipe@2). -spec date(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. date(Dyn) -> (gleam@dynamic:decode1( fun(Field@0) -> {date_time, Field@0} end, gleam@dynamic:field(<<"$date"/utf8>>, fun(V) -> _pipe = V, _pipe@1 = typed_long(_pipe), _pipe@2 = gleam@result:map(_pipe@1, fun(N) -> case N of {int64, N@1} -> {ok, birl:add( {time, 0, 0, none, none}, {duration, N@1 * 1000} )}; _ -> {error, [{decode_error, <<"long"/utf8>>, <<"not long"/utf8>>, []}]} end end), gleam@result:flatten(_pipe@2) end) ))(Dyn). -spec typed_double(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. typed_double(Dyn) -> _pipe = Dyn, _pipe@1 = (gleam@dynamic:field( <<"$numberDouble"/utf8>>, fun gleam@dynamic:string/1 ))(_pipe), _pipe@2 = gleam@result:map(_pipe@1, fun(S) -> case S of <<"NaN"/utf8>> -> {ok, na_n}; <<"infinity"/utf8>> -> {ok, infinity}; <<"-infinity"/utf8>> -> {ok, negative_infinity}; _ -> case gleam@float:parse(S) of {ok, F} -> {ok, {double, F}}; {error, nil} -> {error, [{decode_error, <<"Floating point number, NaN, Infinity or -Infinity"/utf8>>, S, []}]} end end end), gleam@result:flatten(_pipe@2). -spec document(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. document(Dyn) -> (gleam@dynamic:decode1( fun(Field@0) -> {document, Field@0} end, fun(Data) -> case (gleam@dynamic:map(fun gleam@dynamic:string/1, fun value/1))( Data ) of {ok, Map} -> {ok, gleam@map:to_list(Map)}; {error, Error} -> {error, Error} end end ))(Dyn). -spec value(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. value(Dyn) -> case (gleam@dynamic:optional( gleam@dynamic:any( [fun int/1, fun bool/1, fun double/1, fun min/1, fun max/1, fun oid/1, fun date/1, fun code/1, fun binary/1, fun regex/1, fun timestamp/1, fun typed_int/1, fun typed_long/1, fun typed_double/1, fun string/1, fun array/1, fun document/1] ) ))(Dyn) of {ok, {some, Value}} -> {ok, Value}; {ok, none} -> {ok, null}; {error, Error} -> {error, Error} end. -spec from_canonical(binary()) -> {ok, list({binary(), bison@bson:value()})} | {error, gleam@json:decode_error()}. from_canonical(Doc) -> gleam@json:decode( Doc, fun(Data) -> case (gleam@dynamic:map(fun gleam@dynamic:string/1, fun value/1))( Data ) of {ok, Map} -> {ok, gleam@map:to_list(Map)}; {error, Error} -> {error, Error} end end ). -spec array(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. array(Dyn) -> (gleam@dynamic:decode1( fun(Field@0) -> {array, Field@0} end, gleam@dynamic:list(fun value/1) ))(Dyn). -spec timestamp(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. timestamp(Dyn) -> case (gleam@dynamic:field(<<"$timestamp"/utf8>>, fun document/1))(Dyn) of {ok, {document, [{<<"i"/utf8>>, {int32, I}}, {<<"t"/utf8>>, {int32, T}}]}} -> {ok, {timestamp, T, I}}; _ -> {error, [{decode_error, <<"timestamp"/utf8>>, <<"not timestamp"/utf8>>, []}]} end. -spec regex(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. regex(Dyn) -> case (gleam@dynamic:field(<<"$regularExpression"/utf8>>, fun document/1))( Dyn ) of {ok, {document, [{<<"pattern"/utf8>>, {string, Pattern}}, {<<"options"/utf8>>, {string, Options}}]}} -> {ok, {regex, Pattern, Options}}; _ -> {error, [{decode_error, <<"timestamp"/utf8>>, <<"not timestamp"/utf8>>, []}]} end. -spec binary(gleam@dynamic:dynamic_()) -> {ok, bison@bson:value()} | {error, list(gleam@dynamic:decode_error())}. binary(Dyn) -> case (gleam@dynamic:field(<<"$binary"/utf8>>, fun document/1))(Dyn) of {ok, {document, [{<<"base64"/utf8>>, {string, Base64}}, {<<"subType"/utf8>>, {string, Sub_type}}]}} -> case gleam@bit_array:base64_decode(Base64) of {ok, Decoded} -> case Sub_type of <<"00"/utf8>> -> case bison@generic:from_bit_array(Decoded) of {ok, Generic} -> {ok, {binary, {generic, Generic}}}; {error, nil} -> {error, [{decode_error, <<"generic binary"/utf8>>, <<"not generic binary"/utf8>>, []}]} end; <<"04"/utf8>> -> case bison@uuid:from_bit_array(Decoded) of {ok, Uuid} -> {ok, {binary, {uuid, Uuid}}}; {error, nil} -> {error, [{decode_error, <<"uuid binary"/utf8>>, <<"not uuid binary"/utf8>>, []}]} end; <<"05"/utf8>> -> case bison@md5:from_bit_array(Decoded) of {ok, Md5} -> {ok, {binary, {md5, Md5}}}; {error, nil} -> {error, [{decode_error, <<"md5 binary"/utf8>>, <<"not md5 binary"/utf8>>, []}]} end; _ -> case gleam@int:parse(Sub_type) of {ok, Code} -> case bison@custom:from_bit_array_with_code( Code, Decoded ) of {ok, Custom} -> {ok, {binary, {custom, Custom}}}; {error, nil} -> {error, [{decode_error, <<"valid custom binary code"/utf8>>, <<"invalid custom binary code"/utf8>>, []}]} end; {error, nil} -> {error, [{decode_error, <<"valid custom binary code"/utf8>>, <<"invalid custom binary code"/utf8>>, []}]} end end; {error, nil} -> {error, [{decode_error, <<"binary"/utf8>>, <<"not binary"/utf8>>, []}]} end; _ -> {error, [{decode_error, <<"binary"/utf8>>, <<"not binary"/utf8>>, []}]} end.