-module(squirrel@internal@query). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([add_types/3, string/1, var/2, list/1, from_file/1, 'fun'/3, record/2, pipe_call/3, decoder/2, generate_code/2]). -export_type([untyped_query/0, typed_query/0]). -type untyped_query() :: {untyped_query, binary(), integer(), squirrel@internal@gleam:value_identifier(), list(binary()), binary()}. -type typed_query() :: {typed_query, binary(), integer(), squirrel@internal@gleam:value_identifier(), list(binary()), binary(), list(squirrel@internal@gleam:type()), list(squirrel@internal@gleam:field())}. -spec add_types( untyped_query(), list(squirrel@internal@gleam:type()), list(squirrel@internal@gleam:field()) ) -> typed_query(). add_types(Query, Params, Returns) -> {untyped_query, File, Starting_line, Name, Comment, Content} = Query, {typed_query, File, Starting_line, Name, Comment, Content, Params, Returns}. -spec gleam_type_to_decoder(squirrel@internal@gleam:type()) -> binary(). gleam_type_to_decoder(Type_) -> case Type_ of {list, Type_@1} -> <<<<"decode.list("/utf8, (gleam_type_to_decoder(Type_@1))/binary>>/binary, ")"/utf8>>; int -> <<"decode.int"/utf8>>; float -> <<"decode.float"/utf8>>; bool -> <<"decode.bool"/utf8>>; string -> <<"decode.string"/utf8>>; {option, Type_@2} -> <<<<"decode.optional("/utf8, (gleam_type_to_decoder(Type_@2))/binary>>/binary, ")"/utf8>>; json -> <<"decode.string"/utf8>> end. -spec gleam_type_to_encoder(squirrel@internal@gleam:type(), binary()) -> binary(). gleam_type_to_encoder(Type_, Name) -> case Type_ of {list, Type_@1} -> <<<<<<<<"pgo.array(list.map("/utf8, Name/binary>>/binary, ", fn(a) {"/utf8>>/binary, (gleam_type_to_encoder(Type_@1, <<"a"/utf8>>))/binary>>/binary, "}))"/utf8>>; {option, Type_@2} -> <<<<<<<<"pgo.nullable(fn(a) {"/utf8, (gleam_type_to_encoder(Type_@2, <<"a"/utf8>>))/binary>>/binary, "}, "/utf8>>/binary, Name/binary>>/binary, ")"/utf8>>; int -> <<<<"pgo.int("/utf8, Name/binary>>/binary, ")"/utf8>>; float -> <<<<"pgo.float("/utf8, Name/binary>>/binary, ")"/utf8>>; bool -> <<<<"pgo.bool("/utf8, Name/binary>>/binary, ")"/utf8>>; string -> <<<<"pgo.text("/utf8, Name/binary>>/binary, ")"/utf8>>; json -> <<<<"pgo.text(json.to_string("/utf8, Name/binary>>/binary, "))"/utf8>> end. -spec string(binary()) -> glam@doc:document(). string(Content) -> Escaped_string = begin _pipe = Content, _pipe@1 = gleam@string:replace(_pipe, <<"\\"/utf8>>, <<"\\\\"/utf8>>), _pipe@2 = gleam@string:replace(_pipe@1, <<"\""/utf8>>, <<"\\\""/utf8>>), glam@doc:from_string(_pipe@2) end, _pipe@3 = [glam@doc:from_string(<<"\""/utf8>>), Escaped_string, glam@doc:from_string(<<"\""/utf8>>)], glam@doc:concat(_pipe@3). -spec append_if(list(SJC), boolean(), SJC) -> list(SJC). append_if(List, Cond, Value) -> case Cond of true -> [Value | List]; false -> List end. -spec var(binary(), glam@doc:document()) -> glam@doc:document(). var(Name, Body) -> _pipe@3 = [glam@doc:from_string( <<<<"let "/utf8, Name/binary>>/binary, " ="/utf8>> ), begin _pipe = [{break, <<" "/utf8>>, <<""/utf8>>}, Body], _pipe@1 = glam@doc:concat(_pipe), _pipe@2 = glam@doc:group(_pipe@1), glam@doc:nest(_pipe@2, 2) end], glam@doc:concat(_pipe@3). -spec block(list(glam@doc:document())) -> glam@doc:document(). block(Body) -> _pipe@2 = [glam@doc:from_string(<<"{"/utf8>>), begin _pipe = [{line, 1} | Body], _pipe@1 = glam@doc:concat(_pipe), glam@doc:nest(_pipe@1, 2) end, {line, 1}, glam@doc:from_string(<<"}"/utf8>>)], _pipe@3 = glam@doc:concat(_pipe@2), glam@doc:force_break(_pipe@3). -spec call_block(binary(), list(glam@doc:document())) -> glam@doc:document(). call_block(Function, Body) -> _pipe = [glam@doc:from_string(<>), block(Body), glam@doc:from_string(<<")"/utf8>>)], _pipe@1 = glam@doc:concat(_pipe), glam@doc:group(_pipe@1). -spec comma_list(binary(), list(glam@doc:document()), binary()) -> glam@doc:document(). comma_list(Open, Content, Close) -> _pipe@3 = [glam@doc:from_string(Open), begin _pipe = [{break, <<""/utf8>>, <<""/utf8>>}, glam@doc:join( Content, glam@doc:break(<<", "/utf8>>, <<","/utf8>>) )], _pipe@1 = glam@doc:concat(_pipe), _pipe@2 = glam@doc:group(_pipe@1), glam@doc:nest(_pipe@2, 2) end, glam@doc:break(<<""/utf8>>, <<","/utf8>>), glam@doc:from_string(Close)], _pipe@4 = glam@doc:concat(_pipe@3), glam@doc:group(_pipe@4). -spec list(list(glam@doc:document())) -> glam@doc:document(). list(Elems) -> comma_list(<<"["/utf8>>, Elems, <<"]"/utf8>>). -spec do_take_comment(binary(), list(binary())) -> list(binary()). do_take_comment(Query, Lines) -> case gleam@string:trim_left(Query) of <<"--"/utf8, Rest/binary>> -> case gleam@string:split_once(Rest, <<"\n"/utf8>>) of {ok, {Line, Rest@1}} -> do_take_comment(Rest@1, [gleam@string:trim(Line) | Lines]); _ -> do_take_comment( <<""/utf8>>, [gleam@string:trim(Rest) | Lines] ) end; _ -> lists:reverse(Lines) end. -spec take_comment(binary()) -> list(binary()). take_comment(Query) -> do_take_comment(Query, []). -spec from_file(binary()) -> {ok, untyped_query()} | {error, squirrel@internal@error:error()}. from_file(File) -> Read_file = begin _pipe = simplifile:read(File), gleam@result:map_error( _pipe, fun(_capture) -> {cannot_read_file, File, _capture} end ) end, gleam@result:'try'( Read_file, fun(Content) -> File_name = begin _pipe@1 = filepath:base_name(File), filepath:strip_extension(_pipe@1) end, Name = begin _pipe@2 = squirrel@internal@gleam:identifier(File_name), gleam@result:map_error( _pipe@2, fun(_capture@1) -> {query_file_has_invalid_name, File, begin _pipe@3 = squirrel@internal@gleam:similar_identifier_string( File_name ), gleam@option:from_result(_pipe@3) end, _capture@1} end ) end, gleam@result:'try'( Name, fun(Name@1) -> {ok, {untyped_query, File, 1, Name@1, take_comment(Content), Content}} end ) end ). -spec 'fun'(binary(), list(binary()), list(glam@doc:document())) -> glam@doc:document(). 'fun'(Name, Args, Body) -> Args@1 = gleam@list:map(Args, fun glam@doc:from_string/1), _pipe@1 = [glam@doc:from_string(<<"pub fn "/utf8, Name/binary>>), comma_list(<<"("/utf8>>, Args@1, <<") "/utf8>>), block( [begin _pipe = Body, glam@doc:join(_pipe, glam@doc:lines(2)) end] ), {line, 1}], _pipe@2 = glam@doc:concat(_pipe@1), glam@doc:group(_pipe@2). -spec call(binary(), list(glam@doc:document())) -> glam@doc:document(). call(Function, Args) -> _pipe = [glam@doc:from_string(Function), comma_list(<<"("/utf8>>, Args, <<")"/utf8>>)], _pipe@1 = glam@doc:concat(_pipe), glam@doc:group(_pipe@1). -spec gleam_type_to_field_type(squirrel@internal@gleam:type()) -> glam@doc:document(). gleam_type_to_field_type(Type_) -> case Type_ of {list, Type_@1} -> call(<<"List"/utf8>>, [gleam_type_to_field_type(Type_@1)]); {option, Type_@2} -> call(<<"Option"/utf8>>, [gleam_type_to_field_type(Type_@2)]); int -> glam@doc:from_string(<<"Int"/utf8>>); float -> glam@doc:from_string(<<"Float"/utf8>>); bool -> glam@doc:from_string(<<"Bool"/utf8>>); string -> glam@doc:from_string(<<"String"/utf8>>); json -> glam@doc:from_string(<<"String"/utf8>>) end. -spec record(binary(), list(squirrel@internal@gleam:field())) -> glam@doc:document(). record(Name, Fields) -> Fields@1 = gleam@list:map( Fields, fun(Field) -> Label = squirrel@internal@gleam:identifier_to_string( erlang:element(2, Field) ), _pipe = [glam@doc:from_string(<