-module(oaspec@internal@util@naming). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/oaspec/internal/util/naming.gleam"). -export([synthetic_list_suffix/2, capitalize/1, to_pascal_case/1, schema_to_type_name/1, inline_enum_type_name/3, to_snake_case/1, operation_to_function_name/1, deduplicate_names/1]). -export_type([regexes/0, regex_cache_key/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(false). -type regexes() :: {regexes, gleam@regexp:regexp(), gleam@regexp:regexp(), gleam@regexp:regexp()}. -type regex_cache_key() :: oaspec_naming_regexes. -file("src/oaspec/internal/util/naming.gleam", 39). ?DOC(false). -spec compile_regexes() -> regexes(). compile_regexes() -> Word_separator@1 = case gleam@regexp:from_string(<<"[_\\-\\s./]+"/utf8>>) of {ok, Word_separator} -> Word_separator; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"oaspec/internal/util/naming"/utf8>>, function => <<"compile_regexes"/utf8>>, line => 41, value => _assert_fail, start => 1264, 'end' => 1330, pattern_start => 1275, pattern_end => 1293}) end, Camel_case@1 = case gleam@regexp:from_string( <<"([A-Z]+(?=[A-Z][a-z])|[A-Z]?[a-z]+[0-9]*|[A-Z]+[0-9]*|[0-9]+)"/utf8>> ) of {ok, Camel_case} -> Camel_case; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"oaspec/internal/util/naming"/utf8>>, function => <<"compile_regexes"/utf8>>, line => 63, value => _assert_fail@1, start => 2574, 'end' => 2702, pattern_start => 2585, pattern_end => 2599}) end, Underscore_before_caps@1 = case gleam@regexp:from_string( <<"([a-z0-9])([A-Z])"/utf8>> ) of {ok, Underscore_before_caps} -> Underscore_before_caps; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"oaspec/internal/util/naming"/utf8>>, function => <<"compile_regexes"/utf8>>, line => 68, value => _assert_fail@2, start => 2765, 'end' => 2848, pattern_start => 2776, pattern_end => 2802}) end, {regexes, Word_separator@1, Camel_case@1, Underscore_before_caps@1}. -file("src/oaspec/internal/util/naming.gleam", 35). ?DOC(false). -spec cached_regexes() -> regexes(). cached_regexes() -> oaspec_naming_ffi:memoize(oaspec_naming_regexes, fun compile_regexes/0). -file("src/oaspec/internal/util/naming.gleam", 156). ?DOC(false). -spec synthetic_list_suffix(binary(), list(binary())) -> binary(). synthetic_list_suffix(Base_name, Schema_names) -> gleam@bool:guard( gleam@list:contains(Schema_names, <>), <<"_list_items"/utf8>>, fun() -> <<"_list"/utf8>> end ). -file("src/oaspec/internal/util/naming.gleam", 195). ?DOC(false). -spec bump_inline_enum_suffix(binary(), integer(), list(binary())) -> binary(). bump_inline_enum_suffix(Base, Suffix, Taken) -> Candidate = <>, case gleam@list:contains(Taken, Candidate) of false -> Candidate; true -> bump_inline_enum_suffix(Base, Suffix + 1, Taken) end. -file("src/oaspec/internal/util/naming.gleam", 221). ?DOC(false). -spec rewrite_dot_segments(binary()) -> binary(). rewrite_dot_segments(Input) -> _pipe = Input, _pipe@1 = gleam@string:replace( _pipe, <<"_dot_"/utf8>>, <<"_dot_literal_"/utf8>> ), gleam@string:replace(_pipe@1, <<"."/utf8>>, <<"_dot_"/utf8>>). -file("src/oaspec/internal/util/naming.gleam", 232). ?DOC(false). -spec rewrite_leading_signs(binary()) -> binary(). rewrite_leading_signs(Input) -> case gleam_stdlib:string_pop_grapheme(Input) of {ok, {<<"+"/utf8>>, Rest}} -> <<"plus_"/utf8, Rest/binary>>; {ok, {<<"-"/utf8>>, Rest@1}} -> <<"minus_"/utf8, Rest@1/binary>>; _ -> Input end. -file("src/oaspec/internal/util/naming.gleam", 259). ?DOC(false). -spec is_digit(binary()) -> boolean(). is_digit(Grapheme) -> case Grapheme of <<"0"/utf8>> -> true; <<"1"/utf8>> -> true; <<"2"/utf8>> -> true; <<"3"/utf8>> -> true; <<"4"/utf8>> -> true; <<"5"/utf8>> -> true; <<"6"/utf8>> -> true; <<"7"/utf8>> -> true; <<"8"/utf8>> -> true; <<"9"/utf8>> -> true; _ -> false end. -file("src/oaspec/internal/util/naming.gleam", 103). ?DOC(false). -spec ensure_letter_start_pascal(binary()) -> binary(). ensure_letter_start_pascal(Input) -> case gleam_stdlib:string_pop_grapheme(Input) of {ok, {First, _}} -> case is_digit(First) of true -> <<"N"/utf8, Input/binary>>; false -> Input end; {error, _} -> Input end. -file("src/oaspec/internal/util/naming.gleam", 245). ?DOC(false). -spec ensure_letter_start(binary()) -> binary(). ensure_letter_start(Input) -> case gleam_stdlib:string_pop_grapheme(Input) of {ok, {First, _}} -> case is_digit(First) of true -> <<"n_"/utf8, Input/binary>>; false -> Input end; {error, _} -> Input end. -file("src/oaspec/internal/util/naming.gleam", 267). ?DOC(false). -spec escape_keyword(binary()) -> binary(). escape_keyword(Name) -> case Name of <<"as"/utf8>> -> <>; <<"assert"/utf8>> -> <>; <<"auto"/utf8>> -> <>; <<"case"/utf8>> -> <>; <<"const"/utf8>> -> <>; <<"external"/utf8>> -> <>; <<"fn"/utf8>> -> <>; <<"if"/utf8>> -> <>; <<"import"/utf8>> -> <>; <<"let"/utf8>> -> <>; <<"opaque"/utf8>> -> <>; <<"panic"/utf8>> -> <>; <<"pub"/utf8>> -> <>; <<"test"/utf8>> -> <>; <<"todo"/utf8>> -> <>; <<"type"/utf8>> -> <>; <<"use"/utf8>> -> <>; _ -> Name end. -file("src/oaspec/internal/util/naming.gleam", 303). ?DOC(false). -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/internal/util/naming.gleam", 320). ?DOC(false). -spec split_camel_case(binary(), regexes()) -> list(binary()). split_camel_case(Input, Re) -> Matches = gleam@regexp:scan(erlang:element(3, Re), Input), case Matches of [] -> [Input]; _ -> gleam@list:map( Matches, fun(M) -> {match, Content, _} = M, Content end ) end. -file("src/oaspec/internal/util/naming.gleam", 312). ?DOC(false). -spec split_words(binary(), regexes()) -> list(binary()). split_words(Input, Re) -> Parts = gleam@regexp:split(erlang:element(2, Re), Input), _pipe = Parts, _pipe@1 = gleam@list:flat_map( _pipe, fun(_capture) -> split_camel_case(_capture, Re) end ), gleam@list:filter(_pipe@1, fun(S) -> S /= <<""/utf8>> end). -file("src/oaspec/internal/util/naming.gleam", 87). ?DOC(false). -spec to_pascal_case(binary()) -> binary(). to_pascal_case(Input) -> Re = cached_regexes(), _pipe = Input, _pipe@1 = rewrite_dot_segments(_pipe), _pipe@2 = rewrite_leading_signs(_pipe@1), _pipe@3 = split_words(_pipe@2, Re), _pipe@4 = gleam@list:map(_pipe@3, fun capitalize/1), _pipe@5 = gleam@string:join(_pipe@4, <<""/utf8>>), ensure_letter_start_pascal(_pipe@5). -file("src/oaspec/internal/util/naming.gleam", 297). ?DOC(false). -spec schema_to_type_name(binary()) -> binary(). schema_to_type_name(Schema_name) -> _pipe = Schema_name, to_pascal_case(_pipe). -file("src/oaspec/internal/util/naming.gleam", 181). ?DOC(false). -spec inline_enum_type_name(binary(), binary(), list(binary())) -> binary(). inline_enum_type_name(Parent_name, Prop_name, Component_schema_names) -> Base = <<(schema_to_type_name(Parent_name))/binary, (schema_to_type_name(Prop_name))/binary>>, Component_type_names = gleam@list:map( Component_schema_names, fun schema_to_type_name/1 ), case gleam@list:contains(Component_type_names, Base) of false -> Base; true -> bump_inline_enum_suffix(Base, 2, Component_type_names) end. -file("src/oaspec/internal/util/naming.gleam", 333). ?DOC(false). -spec insert_underscores_before_caps(binary(), regexes()) -> binary(). insert_underscores_before_caps(Input, Re) -> gleam_regexp_ffi:replace(erlang:element(4, Re), Input, <<"\\1_\\2"/utf8>>). -file("src/oaspec/internal/util/naming.gleam", 131). ?DOC(false). -spec to_snake_case(binary()) -> binary(). to_snake_case(Input) -> Re = cached_regexes(), Result = begin _pipe = Input, _pipe@1 = rewrite_dot_segments(_pipe), _pipe@2 = rewrite_leading_signs(_pipe@1), _pipe@3 = insert_underscores_before_caps(_pipe@2, Re), _pipe@4 = split_words(_pipe@3, Re), _pipe@5 = gleam@list:map(_pipe@4, fun string:lowercase/1), _pipe@6 = gleam@string:join(_pipe@5, <<"_"/utf8>>), ensure_letter_start(_pipe@6) end, escape_keyword(Result). -file("src/oaspec/internal/util/naming.gleam", 291). ?DOC(false). -spec operation_to_function_name(binary()) -> binary(). operation_to_function_name(Operation_id) -> _pipe = Operation_id, to_snake_case(_pipe). -file("src/oaspec/internal/util/naming.gleam", 339). ?DOC(false). -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 = <<<>/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).