Current section

Files

Jump to
oaspec src oaspec@codegen@server.erl
Raw

src/oaspec@codegen@server.erl

-module(oaspec@codegen@server).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oaspec/codegen/server.gleam").
-export([generate/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-file("src/oaspec/codegen/server.gleam", 41).
?DOC(" Generate a single handler stub.\n").
-spec generate_handler(
gleam@string_tree:string_tree(),
binary(),
oaspec@openapi@spec:operation(),
oaspec@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_handler(Sb, Op_id, Operation, _) ->
Fn_name = oaspec@util@naming:operation_to_function_name(Op_id),
Request_type = <<(oaspec@util@naming:schema_to_type_name(Op_id))/binary,
"Request"/utf8>>,
Response_type = <<(oaspec@util@naming:schema_to_type_name(Op_id))/binary,
"Response"/utf8>>,
Sb@1 = case erlang:element(3, Operation) of
{some, Summary} ->
_pipe = Sb,
oaspec@util@string_extra:doc_comment(_pipe, Summary);
_ ->
Sb
end,
Sb@2 = case erlang:element(4, Operation) of
{some, Desc} ->
_pipe@1 = Sb@1,
oaspec@util@string_extra:doc_comment(_pipe@1, Desc);
_ ->
Sb@1
end,
Has_params = not gleam@list:is_empty(erlang:element(6, Operation)) orelse gleam@option:is_some(
erlang:element(7, Operation)
),
Sb@3 = case Has_params of
true ->
_pipe@2 = Sb@2,
oaspec@util@string_extra:line(
_pipe@2,
<<<<<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(req: request_types."/utf8>>/binary,
Request_type/binary>>/binary,
") -> response_types."/utf8>>/binary,
Response_type/binary>>/binary,
" {"/utf8>>
);
false ->
_pipe@3 = Sb@2,
oaspec@util@string_extra:line(
_pipe@3,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"() -> response_types."/utf8>>/binary,
Response_type/binary>>/binary,
" {"/utf8>>
)
end,
Sb@4 = case Has_params of
true ->
_pipe@4 = Sb@3,
oaspec@util@string_extra:indent(_pipe@4, 1, <<"let _ = req"/utf8>>);
false ->
Sb@3
end,
_pipe@5 = Sb@4,
_pipe@6 = oaspec@util@string_extra:indent(
_pipe@5,
1,
<<"// TODO: Implement "/utf8, Fn_name/binary>>
),
_pipe@7 = oaspec@util@string_extra:indent(_pipe@6, 1, <<"todo"/utf8>>),
_pipe@8 = oaspec@util@string_extra:line(_pipe@7, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@8).
-file("src/oaspec/codegen/server.gleam", 21).
?DOC(" Generate handler stubs for all operations.\n").
-spec generate_handlers(oaspec@codegen@context:context()) -> binary().
generate_handlers(Ctx) ->
Sb = begin
_pipe = oaspec@util@string_extra:file_header(<<"0.3.0"/utf8>>),
oaspec@util@string_extra:imports(
_pipe,
[<<(erlang:element(5, erlang:element(3, Ctx)))/binary,
"/request_types"/utf8>>,
<<(erlang:element(5, erlang:element(3, Ctx)))/binary,
"/response_types"/utf8>>]
)
end,
Operations = oaspec@codegen@types:collect_operations(Ctx),
Sb@2 = gleam@list:fold(
Operations,
Sb,
fun(Sb@1, Op) ->
{Op_id, Operation, _, _} = Op,
generate_handler(Sb@1, Op_id, Operation, Ctx)
end
),
oaspec@util@string_extra:to_string(Sb@2).
-file("src/oaspec/codegen/server.gleam", 157).
?DOC(" Check if a path segment is a parameter.\n").
-spec is_path_param(binary()) -> boolean().
is_path_param(Segment) ->
case Segment of
<<"{"/utf8, _/binary>> ->
true;
_ ->
false
end.
-file("src/oaspec/codegen/server.gleam", 172).
?DOC(" Simple string split (avoiding import issues).\n").
-spec string_split(binary(), binary()) -> list(binary()).
string_split(Input, Delimiter) ->
string:split(Input, Delimiter).
-file("src/oaspec/codegen/server.gleam", 184).
?DOC(" Simple string replace.\n").
-spec string_replace(binary(), binary(), binary()) -> binary().
string_replace(Input, Pattern, Replacement) ->
gleam_stdlib:string_replace(Input, Pattern, Replacement).
-file("src/oaspec/codegen/server.gleam", 165).
?DOC(" Extract parameter name from {name}.\n").
-spec extract_param_name(binary()) -> binary().
extract_param_name(Segment) ->
_pipe = Segment,
_pipe@1 = string_replace(_pipe, <<"{"/utf8>>, <<""/utf8>>),
string_replace(_pipe@1, <<"}"/utf8>>, <<""/utf8>>).
-file("src/oaspec/codegen/server.gleam", 136).
?DOC(" Convert an OpenAPI path to a Gleam pattern match expression.\n").
-spec path_to_pattern(binary()) -> binary().
path_to_pattern(Path) ->
Segments = begin
_pipe = Path,
_pipe@1 = string_split(_pipe, <<"/"/utf8>>),
gleam@list:filter(_pipe@1, fun(S) -> S /= <<""/utf8>> end)
end,
Patterns = gleam@list:map(Segments, fun(Seg) -> case is_path_param(Seg) of
true ->
Param_name = extract_param_name(Seg),
oaspec@util@naming:to_snake_case(Param_name);
false ->
<<<<"\""/utf8, Seg/binary>>/binary, "\""/utf8>>
end end),
<<<<"["/utf8,
(oaspec@util@string_extra:join_with(Patterns, <<", "/utf8>>))/binary>>/binary,
"]"/utf8>>.
-file("src/oaspec/codegen/server.gleam", 96).
?DOC(" Generate a router module that dispatches requests.\n").
-spec generate_router(oaspec@codegen@context:context()) -> binary().
generate_router(Ctx) ->
Sb = begin
_pipe = oaspec@util@string_extra:file_header(<<"0.3.0"/utf8>>),
oaspec@util@string_extra:imports(
_pipe,
[<<(erlang:element(5, erlang:element(3, Ctx)))/binary,
"/handlers"/utf8>>]
)
end,
Sb@1 = begin
_pipe@1 = Sb,
_pipe@2 = oaspec@util@string_extra:doc_comment(
_pipe@1,
<<"Route an incoming request to the appropriate handler."/utf8>>
),
_pipe@3 = oaspec@util@string_extra:line(
_pipe@2,
<<"pub fn route(method: String, path: List(String)) -> String {"/utf8>>
),
oaspec@util@string_extra:indent(
_pipe@3,
1,
<<"case method, path {"/utf8>>
)
end,
Operations = oaspec@codegen@types:collect_operations(Ctx),
Sb@3 = gleam@list:fold(
Operations,
Sb@1,
fun(Sb@2, Op) ->
{Op_id, _, Path, Method} = Op,
Fn_name = oaspec@util@naming:operation_to_function_name(Op_id),
Method_str = oaspec@openapi@spec:method_to_string(Method),
Path_pattern = path_to_pattern(Path),
_pipe@4 = Sb@2,
_pipe@5 = oaspec@util@string_extra:indent(
_pipe@4,
2,
<<<<<<<<"\""/utf8, Method_str/binary>>/binary, "\", "/utf8>>/binary,
Path_pattern/binary>>/binary,
" -> {"/utf8>>
),
_pipe@6 = oaspec@util@string_extra:indent(
_pipe@5,
3,
<<"let _ = handlers."/utf8, Fn_name/binary>>
),
_pipe@7 = oaspec@util@string_extra:indent(
_pipe@6,
3,
<<"\"OK\""/utf8>>
),
oaspec@util@string_extra:indent(_pipe@7, 2, <<"}"/utf8>>)
end
),
Sb@4 = begin
_pipe@8 = Sb@3,
_pipe@9 = oaspec@util@string_extra:indent(
_pipe@8,
2,
<<"_, _ -> \"Not Found\""/utf8>>
),
_pipe@10 = oaspec@util@string_extra:indent(_pipe@9, 1, <<"}"/utf8>>),
_pipe@11 = oaspec@util@string_extra:line(_pipe@10, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@11)
end,
oaspec@util@string_extra:to_string(Sb@4).
-file("src/oaspec/codegen/server.gleam", 10).
?DOC(" Generate server stub files.\n").
-spec generate(oaspec@codegen@context:context()) -> list(oaspec@codegen@context:generated_file()).
generate(Ctx) ->
Handlers_content = generate_handlers(Ctx),
Router_content = generate_router(Ctx),
[{generated_file, <<"handlers.gleam"/utf8>>, Handlers_content},
{generated_file, <<"router.gleam"/utf8>>, Router_content}].