Current section

Files

Jump to
oaspec src oaspec@util@naming.erl
Raw

src/oaspec@util@naming.erl

-module(oaspec@util@naming).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oaspec/util/naming.gleam").
-export([capitalize/1, to_pascal_case/1, schema_to_type_name/1, to_snake_case/1, operation_to_function_name/1, to_module_name/1, deduplicate_names/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/util/naming.gleam", 30).
?DOC(" Gleam reserved keywords that cannot be used as identifiers.\n").
-spec escape_keyword(binary()) -> binary().
escape_keyword(Name) ->
case Name of
<<"as"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"assert"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"auto"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"case"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"const"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"external"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"fn"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"if"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"import"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"let"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"opaque"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"panic"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"pub"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"test"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"todo"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"type"/utf8>> ->
<<Name/binary, "_"/utf8>>;
<<"use"/utf8>> ->
<<Name/binary, "_"/utf8>>;
_ ->
Name
end.
-file("src/oaspec/util/naming.gleam", 72).
?DOC(" Capitalize the first letter of a string.\n").
-spec capitalize(binary()) -> binary().
capitalize(Input) ->
case gleam_stdlib:string_pop_grapheme(Input) of
{ok, {First, Rest}} ->
<<(string:uppercase(First))/binary, Rest/binary>>;
{error, _} ->
Input
end.
-file("src/oaspec/util/naming.gleam", 89).
?DOC(" Split camelCase/PascalCase into separate words.\n").
-spec split_camel_case(binary()) -> list(binary()).
split_camel_case(Input) ->
Re@1 = case gleam@regexp:from_string(
<<"([A-Z]+(?=[A-Z][a-z])|[A-Z]?[a-z]+|[A-Z]+|[0-9]+)"/utf8>>
) of
{ok, Re} -> Re;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"oaspec/util/naming"/utf8>>,
function => <<"split_camel_case"/utf8>>,
line => 90,
value => _assert_fail,
start => 2218,
'end' => 2313,
pattern_start => 2229,
pattern_end => 2235})
end,
Matches = gleam@regexp:scan(Re@1, Input),
case Matches of
[] ->
[Input];
_ ->
gleam@list:map(
Matches,
fun(M) ->
{match, Content, _} = M,
Content
end
)
end.
-file("src/oaspec/util/naming.gleam", 80).
?DOC(" Split a string into words by common separators.\n").
-spec split_words(binary()) -> list(binary()).
split_words(Input) ->
Re@1 = case gleam@regexp:from_string(<<"[_\\-\\s./]+"/utf8>>) of
{ok, Re} -> Re;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"oaspec/util/naming"/utf8>>,
function => <<"split_words"/utf8>>,
line => 81,
value => _assert_fail,
start => 1934,
'end' => 1988,
pattern_start => 1945,
pattern_end => 1951})
end,
Parts = gleam@regexp:split(Re@1, Input),
_pipe = Parts,
_pipe@1 = gleam@list:flat_map(_pipe, fun split_camel_case/1),
gleam@list:filter(_pipe@1, fun(S) -> S /= <<""/utf8>> end).
-file("src/oaspec/util/naming.gleam", 9).
?DOC(
" Convert a string to PascalCase for Gleam type names.\n"
" Examples: \"pet_store\" -> \"PetStore\", \"get-user\" -> \"GetUser\"\n"
).
-spec to_pascal_case(binary()) -> binary().
to_pascal_case(Input) ->
_pipe = Input,
_pipe@1 = split_words(_pipe),
_pipe@2 = gleam@list:map(_pipe@1, fun capitalize/1),
gleam@string:join(_pipe@2, <<""/utf8>>).
-file("src/oaspec/util/naming.gleam", 60).
?DOC(" Convert an OpenAPI schema name to a valid Gleam type name.\n").
-spec schema_to_type_name(binary()) -> binary().
schema_to_type_name(Schema_name) ->
_pipe = Schema_name,
to_pascal_case(_pipe).
-file("src/oaspec/util/naming.gleam", 104).
?DOC(" Insert underscores before capital letters in camelCase strings.\n").
-spec insert_underscores_before_caps(binary()) -> binary().
insert_underscores_before_caps(Input) ->
Re@1 = case gleam@regexp:from_string(<<"([a-z0-9])([A-Z])"/utf8>>) of
{ok, Re} -> Re;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"oaspec/util/naming"/utf8>>,
function => <<"insert_underscores_before_caps"/utf8>>,
line => 105,
value => _assert_fail,
start => 2634,
'end' => 2693,
pattern_start => 2645,
pattern_end => 2651})
end,
gleam_regexp_ffi:replace(Re@1, Input, <<"\\1_\\2"/utf8>>).
-file("src/oaspec/util/naming.gleam", 19).
?DOC(
" Convert a string to snake_case for Gleam function/variable names.\n"
" Examples: \"PetStore\" -> \"pet_store\", \"getUserById\" -> \"get_user_by_id\"\n"
" Gleam keywords are suffixed with _ to avoid syntax errors.\n"
).
-spec to_snake_case(binary()) -> binary().
to_snake_case(Input) ->
Result = begin
_pipe = Input,
_pipe@1 = insert_underscores_before_caps(_pipe),
_pipe@2 = split_words(_pipe@1),
_pipe@3 = gleam@list:map(_pipe@2, fun string:lowercase/1),
gleam@string:join(_pipe@3, <<"_"/utf8>>)
end,
escape_keyword(Result).
-file("src/oaspec/util/naming.gleam", 54).
?DOC(" Convert an OpenAPI operation ID to a valid Gleam function name.\n").
-spec operation_to_function_name(binary()) -> binary().
operation_to_function_name(Operation_id) ->
_pipe = Operation_id,
to_snake_case(_pipe).
-file("src/oaspec/util/naming.gleam", 66).
?DOC(" Convert an OpenAPI schema name to a valid Gleam module name.\n").
-spec to_module_name(binary()) -> binary().
to_module_name(Name) ->
_pipe = Name,
to_snake_case(_pipe).
-file("src/oaspec/util/naming.gleam", 111).
?DOC(
" Deduplicate a list of names by appending _2, _3, etc. to duplicates.\n"
" Preserves order. First occurrence keeps original name.\n"
).
-spec deduplicate_names(list(binary())) -> list(binary()).
deduplicate_names(Names) ->
{Result_rev, _} = gleam@list:fold(
Names,
{[], maps:new()},
fun(Acc, Name) ->
{Result, Counts} = Acc,
case gleam_stdlib:map_get(Counts, Name) of
{error, _} ->
Counts@1 = gleam@dict:insert(Counts, Name, 1),
{[Name | Result], Counts@1};
{ok, Count} ->
New_count = Count + 1,
Unique_name = <<<<Name/binary, "_"/utf8>>/binary,
(erlang:integer_to_binary(New_count))/binary>>,
Counts@2 = gleam@dict:insert(Counts, Name, New_count),
{[Unique_name | Result], Counts@2}
end
end
),
lists:reverse(Result_rev).