-module(parrot@codegen). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([sqlc_type_to_gleam/1, gen_query_type/1, gen_query_function/1, gen_query_decoder/1, comment_dont_edit/0, gen_gleam_module/1, codegen_from_config/1]). -file("src/parrot/codegen.gleam", 43). -spec sqlc_type_to_gleam(binary()) -> binary(). sqlc_type_to_gleam(Sqltype) -> case string:lowercase(Sqltype) of <<"integer"/utf8>> -> <<"Int"/utf8>>; <<"bigint"/utf8>> -> <<"Int"/utf8>>; <<"bigserial"/utf8>> -> <<"Int"/utf8>>; <<"text"/utf8>> -> <<"String"/utf8>>; <<"datetime"/utf8>> -> <<"Timestamp"/utf8>>; _ -> erlang:error(#{gleam_error => panic, message => (<<"unknown type mapping: "/utf8, Sqltype/binary>>), module => <<"parrot/codegen"/utf8>>, function => <<"sqlc_type_to_gleam"/utf8>>, line => 48}) end. -file("src/parrot/codegen.gleam", 52). -spec gen_query_type(parrot@internal@sqlc:'query'()) -> binary(). gen_query_type(Query) -> Name = parrot@internal@string_case:pascal_case(erlang:element(3, Query)), Args = begin _pipe = erlang:element(6, Query), _pipe@1 = gleam@list:map( _pipe, fun(Col) -> Col_type = sqlc_type_to_gleam( erlang:element(4, erlang:element(16, Col)) ), Col_type@1 = case erlang:element(3, Col) of true -> Col_type; false -> <<<<"Option("/utf8, Col_type/binary>>/binary, ")"/utf8>> end, <<<<(erlang:element(2, Col))/binary, ": "/utf8>>/binary, Col_type@1/binary>> end ), _pipe@2 = gleam@list:map( _pipe@1, fun(Str) -> <<" "/utf8, Str/binary>> end ), gleam@string:join(_pipe@2, <<",\n"/utf8>>) end, _pipe@3 = [<<<<"pub type "/utf8, Name/binary>>/binary, " {"/utf8>>, <<<<" "/utf8, Name/binary>>/binary, "("/utf8>>, Args, <<" )"/utf8>>, <<"}"/utf8>>], gleam@string:join(_pipe@3, <<"\n"/utf8>>). -file("src/parrot/codegen.gleam", 72). -spec gen_query_function(parrot@internal@sqlc:'query'()) -> binary(). gen_query_function(Query) -> Fn_name = parrot@internal@string_case:snake_case(erlang:element(3, Query)), Def_fn_args = begin _pipe = erlang:element(9, Query), _pipe@1 = gleam@list:map( _pipe, fun(P) -> <<<<(erlang:element(2, erlang:element(3, P)))/binary, ": "/utf8>>/binary, (sqlc_type_to_gleam( erlang:element( 4, erlang:element(16, erlang:element(3, P)) ) ))/binary>> end ), gleam@string:join(_pipe@1, <<", "/utf8>>) end, Def_return_params = case erlang:element(9, Query) of [] -> <<"Nil"/utf8>>; Args -> <<<<"#("/utf8, (begin _pipe@2 = Args, _pipe@3 = gleam@list:map( _pipe@2, fun(Arg) -> erlang:element(2, erlang:element(3, Arg)) end ), gleam@string:join(_pipe@3, <<", "/utf8>>) end)/binary>>/binary, ")"/utf8>> end, Def_fn = <<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "("/utf8>>/binary, Def_fn_args/binary>>/binary, ")"/utf8>>, Def_sql = <<<<"let sql = \""/utf8, (erlang:element(2, Query))/binary>>/binary, "\""/utf8>>, Def_return = <<<<"#(sql, "/utf8, Def_return_params/binary>>/binary, ")"/utf8>>, _pipe@4 = [<>, <<" "/utf8, Def_sql/binary>>, <<" "/utf8, Def_return/binary>>, <<"}"/utf8>>], gleam@string:join(_pipe@4, <<"\n"/utf8>>). -file("src/parrot/codegen.gleam", 100). -spec gen_query_decoder(parrot@internal@sqlc:'query'()) -> binary(). gen_query_decoder(Query) -> case erlang:length(erlang:element(6, Query)) of 0 -> <<""/utf8>>; _ -> Type_name = parrot@internal@string_case:pascal_case( erlang:element(3, Query) ), Fn_name = <<(parrot@internal@string_case:snake_case( erlang:element(3, Query) ))/binary, "_decoder"/utf8>>, Decoder_fields = begin _pipe = erlang:element(6, Query), _pipe@1 = gleam@list:map( _pipe, fun(Col) -> Decoder_type = case string:lowercase( erlang:element(4, erlang:element(16, Col)) ) of <<"integer"/utf8>> -> <<"decode.int"/utf8>>; <<"bigint"/utf8>> -> <<"decode.int"/utf8>>; <<"bigserial"/utf8>> -> <<"decode.int"/utf8>>; <<"text"/utf8>> -> <<"decode.string"/utf8>>; <<"datetime"/utf8>> -> <<"datetime_decoder()"/utf8>>; _ -> erlang:error(#{gleam_error => panic, message => (<<"unknown decoder mapping: "/utf8, (erlang:element( 4, erlang:element(16, Col) ))/binary>>), module => <<"parrot/codegen"/utf8>>, function => <<"gen_query_decoder"/utf8>>, line => 114}) end, Decoder = case erlang:element(3, Col) of true -> Decoder_type; false -> <<<<"decode.optional("/utf8, Decoder_type/binary>>/binary, ")"/utf8>> end, <<<<<<<<<<<<" use "/utf8, (erlang:element(2, Col))/binary>>/binary, " <- decode.field(\""/utf8>>/binary, (erlang:element(2, Col))/binary>>/binary, "\", "/utf8>>/binary, Decoder/binary>>/binary, ")"/utf8>> end ), gleam@string:join(_pipe@1, <<"\n"/utf8>>) end, Constructor_args = begin _pipe@2 = erlang:element(6, Query), _pipe@3 = gleam@list:map( _pipe@2, fun(Col@1) -> <<(erlang:element(2, Col@1))/binary, ": "/utf8>> end ), gleam@string:join(_pipe@3, <<", "/utf8>>) end, Success_line = <<<<<<<<" decode.success("/utf8, Type_name/binary>>/binary, "("/utf8>>/binary, Constructor_args/binary>>/binary, "))"/utf8>>, <<<<<<<<<<<<<<<<"\n\npub fn "/utf8, Fn_name/binary>>/binary, "() -> decode.Decoder("/utf8>>/binary, Type_name/binary>>/binary, ") {\n"/utf8>>/binary, Decoder_fields/binary>>/binary, "\n"/utf8>>/binary, Success_line/binary>>/binary, "\n}"/utf8>> end. -file("src/parrot/codegen.gleam", 34). -spec gen_query(parrot@internal@sqlc:'query'()) -> binary(). gen_query(Query) -> Type_str = case erlang:length(erlang:element(6, Query)) of 0 -> <<""/utf8>>; _ -> <<(gen_query_type(Query))/binary, "\n\n"/utf8>> end, <<<>/binary, (gen_query_decoder(Query))/binary>>. -file("src/parrot/codegen.gleam", 153). -spec datetime_decoder_function() -> binary(). datetime_decoder_function() -> <<<<<<<<<<<<<<<<"fn datetime_decoder() -> decode.Decoder(Timestamp) {\n"/utf8, " decode.string\n"/utf8>>/binary, " |> decode.then(fn(datetime_str) {\n"/utf8>>/binary, " case timestamp.parse_rfc3339(datetime_str) {\n"/utf8>>/binary, " Ok(ts) -> decode.success(ts)\n"/utf8>>/binary, " Error(_) -> decode.failure(timestamp.from_unix_seconds(0), \"Invalid datetime format\")\n"/utf8>>/binary, " }\n"/utf8>>/binary, " })\n"/utf8>>/binary, "}"/utf8>>. -file("src/parrot/codegen.gleam", 188). -spec comment_dont_edit() -> binary(). comment_dont_edit() -> _assert_subject = parrot@internal@project:version(), {ok, Version} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"parrot/codegen"/utf8>>, function => <<"comment_dont_edit"/utf8>>, line => 189}) end, _pipe = <<" //// Code generated by parrot. DO NOT EDIT. //// versions: //// parrot v{version} //// "/utf8>>, _pipe@1 = gleam@string:replace(_pipe, <<"{version}"/utf8>>, Version), parrot@internal@lib:dedent(_pipe@1). -file("src/parrot/codegen.gleam", 165). -spec gen_gleam_module(parrot@internal@sqlc:sqlc()) -> binary(). gen_gleam_module(Schema) -> Queries = begin _pipe = erlang:element(6, Schema), _pipe@1 = gleam@list:map(_pipe, fun gen_query/1), gleam@string:join(_pipe@1, <<"\n\n"/utf8>>) end, Imports = <<<<<<<<"import gleam/option.{type Option}"/utf8, "\n"/utf8>>/binary, "import gleam/dynamic/decode"/utf8>>/binary, "\n"/utf8>>/binary, "import gleam/time/timestamp.{type Timestamp}"/utf8>>, <<<<<<<<<<<<<<(comment_dont_edit())/binary, "\n\n"/utf8>>/binary, Imports/binary>>/binary, "\n\n"/utf8>>/binary, "// Custom decoders\n"/utf8>>/binary, (datetime_decoder_function())/binary>>/binary, "\n\n"/utf8>>/binary, Queries/binary>>. -file("src/parrot/codegen.gleam", 15). -spec codegen_from_config(parrot@config:config()) -> {ok, nil} | {error, nil}. codegen_from_config(Config) -> parrot@internal@lib:try_nil( parrot@config:get_json_file(Config), fun(Json_string) -> parrot@internal@lib:try_nil( gleam@json:parse( Json_string, {decoder, fun gleam@dynamic@decode:decode_dynamic/1} ), fun(Dyn_json) -> _assert_subject = parrot@internal@sqlc:decode_sqlc(Dyn_json), {ok, Parsed} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"parrot/codegen"/utf8>>, function => <<"codegen_from_config"/utf8>>, line => 20}) end, Module_contents = gen_gleam_module(Parsed), _ = begin _pipe = parrot@config:get_module_directory(Config), simplifile:create_directory_all(_pipe) end, _ = begin _pipe@1 = simplifile:write( parrot@config:get_module_path(Config), Module_contents ), gleam@io:debug(_pipe@1) end, {ok, nil} end ) end ).