-module(glerd_json). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([generate/2]). -spec decode_tuple( list(glerd@types:field_type(binary())), gleam@dict:dict(binary(), {any(), binary(), list({binary(), glerd@types:field_type(binary())})}) ) -> binary(). decode_tuple(Types, Record_info_dict) -> Arity = begin _pipe = erlang:length(Types), gleam@int:to_string(_pipe) end, Body = begin _pipe@1 = Types, _pipe@2 = gleam@list:map( _pipe@1, fun(Typ) -> decode_field_type(Typ, Record_info_dict) end ), gleam@string:join(_pipe@2, <<","/utf8>>) end, <<<<<<<<"dynamic.tuple"/utf8, Arity/binary>>/binary, "("/utf8>>/binary, Body/binary>>/binary, ")"/utf8>>. -spec decode_field_type( glerd@types:field_type(binary()), gleam@dict:dict(binary(), {any(), binary(), list({binary(), glerd@types:field_type(binary())})}) ) -> binary(). decode_field_type(Typ, Record_info_dict) -> case Typ of is_string -> <<"dynamic.string"/utf8>>; is_int -> <<"dynamic.int"/utf8>>; is_float -> <<"dynamic.float"/utf8>>; is_bool -> <<"dynamic.bool"/utf8>>; {is_list, Typ@1} -> <<<<"dynamic.list("/utf8, (decode_field_type(Typ@1, Record_info_dict))/binary>>/binary, ")"/utf8>>; {is_option, Typ@2} -> <<<<"dynamic.optional("/utf8, (decode_field_type(Typ@2, Record_info_dict))/binary>>/binary, ")"/utf8>>; {is_dict, Key_typ, Val_typ} -> <<<<<<<<"dynamic.dict("/utf8, (decode_field_type(Key_typ, Record_info_dict))/binary>>/binary, ", "/utf8>>/binary, (decode_field_type(Val_typ, Record_info_dict))/binary>>/binary, ")"/utf8>>; {is_tuple2, Typ1, Typ2} -> decode_tuple([Typ1, Typ2], Record_info_dict); {is_tuple3, Typ1@1, Typ2@1, Typ3} -> decode_tuple([Typ1@1, Typ2@1, Typ3], Record_info_dict); {is_tuple4, Typ1@2, Typ2@2, Typ3@1, Typ4} -> decode_tuple([Typ1@2, Typ2@2, Typ3@1, Typ4], Record_info_dict); {is_tuple5, Typ1@3, Typ2@3, Typ3@2, Typ4@1, Typ5} -> decode_tuple( [Typ1@3, Typ2@3, Typ3@2, Typ4@1, Typ5], Record_info_dict ); {is_tuple6, Typ1@4, Typ2@4, Typ3@3, Typ4@2, Typ5@1, Typ6} -> decode_tuple( [Typ1@4, Typ2@4, Typ3@3, Typ4@2, Typ5@1, Typ6], Record_info_dict ); {is_record, Record_name} -> _assert_subject = gleam@dict:get(Record_info_dict, Record_name), {ok, {_, Module_name, Record_fields}} = case _assert_subject of {ok, {_, _, _}} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"glerd_json"/utf8>>, function => <<"decode_field_type"/utf8>>, line => 154}) end, Arity = begin _pipe = erlang:length(Record_fields), gleam@int:to_string(_pipe) end, <<<<<<<<<<<<<<<<"dynamic.decode"/utf8, Arity/binary>>/binary, "( "/utf8>>/binary, Module_name/binary>>/binary, "."/utf8>>/binary, Record_name/binary>>/binary, ", "/utf8>>/binary, (begin _pipe@1 = gleam@list:map( Record_fields, fun(X) -> {Fname, Typ@3} = X, <<<<<<<<"dynamic.field(\""/utf8, Fname/binary>>/binary, "\", "/utf8>>/binary, (decode_field_type( Typ@3, Record_info_dict ))/binary>>/binary, ")"/utf8>> end ), gleam@string:join(_pipe@1, <<",\n"/utf8>>) end)/binary>>/binary, " )"/utf8>>; X@1 -> erlang:error(#{gleam_error => panic, message => (<<"Type decode not supported: "/utf8, (gleam@string:inspect(X@1))/binary>>), module => <<"glerd_json"/utf8>>, function => <<"decode_field_type"/utf8>>, line => 171}) end. -spec encode_tuple( binary(), list(glerd@types:field_type(JTH)), gleam@dict:dict(JTH, {any(), any(), list({binary(), glerd@types:field_type(JTH)})}) ) -> binary(). encode_tuple(Name, Types, Record_info_dict) -> Tuple_body = begin _pipe = Types, _pipe@1 = gleam@list:index_map( _pipe, fun(Typ, I) -> Typ@1 = encode_field_type( <<"__just_type__"/utf8>>, Typ, Record_info_dict ), <<<<<<<<<>/binary, Name/binary>>/binary, "."/utf8>>/binary, (gleam@int:to_string(I))/binary>>/binary, "),"/utf8>> end ), gleam@string:join(_pipe@1, <<"\n"/utf8>>) end, <<<<"json.preprocessed_array(["/utf8, Tuple_body/binary>>/binary, "])"/utf8>>. -spec encode_field_type( binary(), glerd@types:field_type(JTH), gleam@dict:dict(JTH, {any(), any(), list({binary(), glerd@types:field_type(JTH)})}) ) -> binary(). encode_field_type(Name, Typ, Record_info_dict) -> case Typ of is_string when Name =:= <<"__just_type__"/utf8>> -> <<"json.string"/utf8>>; is_string -> <<<<"json.string(x"/utf8, Name/binary>>/binary, ")"/utf8>>; is_bool when Name =:= <<"__just_type__"/utf8>> -> <<"json.bool"/utf8>>; is_bool -> <<<<"json.bool(x"/utf8, Name/binary>>/binary, ")"/utf8>>; is_int when Name =:= <<"__just_type__"/utf8>> -> <<"json.int"/utf8>>; is_int -> <<<<"json.int(x"/utf8, Name/binary>>/binary, ")"/utf8>>; is_float when Name =:= <<"__just_type__"/utf8>> -> <<<<"json.float(x"/utf8, Name/binary>>/binary, ")"/utf8>>; is_float -> <<<<"json.float(x"/utf8, Name/binary>>/binary, ")"/utf8>>; {is_list, Typ@1} -> Nested_type = encode_field_type( <<"__just_type__"/utf8>>, Typ@1, Record_info_dict ), <<<<<<<<"json.array(x"/utf8, Name/binary>>/binary, ", "/utf8>>/binary, Nested_type/binary>>/binary, ")"/utf8>>; {is_option, Typ@2} -> Nested_type@1 = encode_field_type( <<"__just_type__"/utf8>>, Typ@2, Record_info_dict ), <<<<<<<<"json.nullable(x"/utf8, Name/binary>>/binary, ", "/utf8>>/binary, Nested_type@1/binary>>/binary, ")"/utf8>>; {is_tuple2, Typ1, Typ2} -> encode_tuple(Name, [Typ1, Typ2], Record_info_dict); {is_tuple3, Typ1@1, Typ2@1, Typ3} -> encode_tuple(Name, [Typ1@1, Typ2@1, Typ3], Record_info_dict); {is_tuple4, Typ1@2, Typ2@2, Typ3@1, Typ4} -> encode_tuple(Name, [Typ1@2, Typ2@2, Typ3@1, Typ4], Record_info_dict); {is_tuple5, Typ1@3, Typ2@3, Typ3@2, Typ4@1, Typ5} -> encode_tuple( Name, [Typ1@3, Typ2@3, Typ3@2, Typ4@1, Typ5], Record_info_dict ); {is_tuple6, Typ1@4, Typ2@4, Typ3@3, Typ4@2, Typ5@1, Typ6} -> encode_tuple( Name, [Typ1@4, Typ2@4, Typ3@3, Typ4@2, Typ5@1, Typ6], Record_info_dict ); {is_record, Record_name} -> _assert_subject = gleam@dict:get(Record_info_dict, Record_name), {ok, {_, _, Record_fields}} = case _assert_subject of {ok, {_, _, _}} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"glerd_json"/utf8>>, function => <<"encode_field_type"/utf8>>, line => 101}) end, <<<<"json.object(["/utf8, (gleam@list:fold( Record_fields, <<""/utf8>>, fun(Acc, Field) -> {Fname, Typ@3} = Field, Ftype = encode_field_type( <<<>/binary, Fname/binary>>, Typ@3, Record_info_dict ), <<<<<<<<<>/binary, Fname/binary>>/binary, "\", "/utf8>>/binary, Ftype/binary>>/binary, "),"/utf8>> end ))/binary>>/binary, "])"/utf8>>; {is_dict, _, Val_typ} -> Val_typ@1 = encode_field_type( <<"__just_type__"/utf8>>, Val_typ, Record_info_dict ), <<<<<<<<"json.object( x"/utf8, Name/binary>>/binary, " |> dict.to_list |> list.map(fn(x) { #(x.0,"/utf8>>/binary, Val_typ@1/binary>>/binary, "(x.1)) }) )"/utf8>>; X -> erlang:error(#{gleam_error => panic, message => (<<"Type encode not supported: "/utf8, (gleam@string:inspect(X))/binary>>), module => <<"glerd_json"/utf8>>, function => <<"encode_field_type"/utf8>>, line => 124}) end. -spec generate( binary(), list({binary(), binary(), list({binary(), glerd@types:field_type(binary())})}) ) -> nil. generate(Root, Record_info) -> Imports = begin _pipe = Record_info, _pipe@1 = gleam@list:map( _pipe, fun(Ri) -> {_, Module_name, _} = Ri, <<"import "/utf8, Module_name/binary>> end ), _pipe@2 = gleam@list:unique(_pipe@1), gleam@string:join(_pipe@2, <<"\n"/utf8>>) end, Record_info_dict = gleam@list:fold( Record_info, gleam@dict:new(), fun(Acc, Ri@1) -> {Name, _, _} = Ri@1, gleam@dict:insert(Acc, Name, Ri@1) end ), Gen_content = gleam@list:fold( Record_info, <<"// this file was generated via glerd_json import gleam/json import gleam/dynamic import gleam/dict import gleam/list "/utf8, Imports/binary>>, fun(Acc@1, Rinfo) -> {Record_name, Module_name@1, _} = Rinfo, Fn_name_prefix = justin:snake_case(Record_name), Encoded = encode_field_type( <<""/utf8>>, {is_record, Record_name}, Record_info_dict ), Decoded = decode_field_type( {is_record, Record_name}, Record_info_dict ), <<<<<<<<<<<<<<<<<<<<<<<<<>/binary, Fn_name_prefix/binary>>/binary, "_json_encode(x: "/utf8>>/binary, Module_name@1/binary>>/binary, "."/utf8>>/binary, Record_name/binary>>/binary, ") { "/utf8>>/binary, Encoded/binary>>/binary, " |> json.to_string } pub fn "/utf8>>/binary, Fn_name_prefix/binary>>/binary, "_json_decode(s: String) { "/utf8>>/binary, Decoded/binary>>/binary, " |> json.decode(s, _) } "/utf8>> end ), Gen_file_path = <<<<"./"/utf8, Root/binary>>/binary, "/glerd_json_gen.gleam"/utf8>>, _assert_subject = simplifile:write(Gen_file_path, Gen_content), {ok, _} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"glerd_json"/utf8>>, function => <<"generate"/utf8>>, line => 57}) end, _assert_subject@1 = gleamyshell_ffi:execute( <<"gleam"/utf8>>, <<"."/utf8>>, [<<"format"/utf8>>, Gen_file_path] ), {ok, _} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"glerd_json"/utf8>>, function => <<"generate"/utf8>>, line => 59}) end, nil.