-module(squirrel@internal@gleam). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([contains_option/1, identifier/1, identifier_to_string/1, identifier_to_type_name/1, similar_identifier_string/1]). -export_type([type/0, field/0, value_identifier/0]). -type type() :: {list, type()} | {option, type()} | int | float | bool | string. -type field() :: {field, value_identifier(), type()}. -opaque value_identifier() :: {value_identifier, binary()}. -spec contains_option(type()) -> boolean(). contains_option(Type_) -> case Type_ of int -> false; float -> false; bool -> false; string -> false; {option, _} -> true; {list, Type_@1} -> contains_option(Type_@1) end. -spec to_identifier_rest(binary(), binary(), integer()) -> {ok, value_identifier()} | {error, squirrel@internal@error:value_identifier_error()}. to_identifier_rest(Name, Rest, Position) -> case Rest of <<"a"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"b"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"c"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"d"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"e"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"f"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"g"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"h"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"i"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"j"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"k"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"l"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"m"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"n"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"o"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"p"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"q"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"r"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"s"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"t"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"u"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"v"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"w"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"x"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"y"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"z"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"_"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"0"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"1"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"2"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"3"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"4"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"5"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"6"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"7"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"8"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<"9"/utf8, Rest@1/binary>> -> to_identifier_rest(Name, Rest@1, Position + 1); <<""/utf8>> -> {ok, {value_identifier, Name}}; _ -> case gleam@string:pop_grapheme(Rest) of {ok, {G, _}} -> {error, {contains_invalid_grapheme, Position, G}}; {error, _} -> erlang:error(#{gleam_error => panic, message => <<"unreachable: empty identifier rest should be ok"/utf8>>, module => <<"squirrel/internal/gleam"/utf8>>, function => <<"to_identifier_rest"/utf8>>, line => 140}) end end. -spec identifier(binary()) -> {ok, value_identifier()} | {error, squirrel@internal@error:value_identifier_error()}. identifier(Name) -> case Name of <<"a"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"b"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"c"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"d"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"e"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"f"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"g"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"h"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"i"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"j"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"k"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"l"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"m"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"n"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"o"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"p"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"q"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"r"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"s"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"t"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"u"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"v"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"w"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"x"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"y"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); <<"z"/utf8, Rest/binary>> -> to_identifier_rest(Name, Rest, 1); _ -> case gleam@string:pop_grapheme(Name) of {ok, {G, _}} -> {error, {contains_invalid_grapheme, 0, G}}; {error, _} -> {error, is_empty} end end. -spec identifier_to_string(value_identifier()) -> binary(). identifier_to_string(Identifier) -> {value_identifier, Name} = Identifier, Name. -spec identifier_to_type_name(value_identifier()) -> binary(). identifier_to_type_name(Identifier) -> {value_identifier, Name} = Identifier, _pipe = justin:pascal_case(Name), _pipe@1 = gleam@string:to_graphemes(_pipe), _pipe@2 = gleam@list:filter(_pipe@1, fun(C) -> C /= <<"_"/utf8>> end), gleam@string:join(_pipe@2, <<""/utf8>>). -spec is_digit(binary()) -> boolean(). is_digit(Char) -> case Char 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. -spec is_identifier_char(binary()) -> boolean(). is_identifier_char(Char) -> case Char of <<"a"/utf8>> -> true; <<"b"/utf8>> -> true; <<"c"/utf8>> -> true; <<"d"/utf8>> -> true; <<"e"/utf8>> -> true; <<"f"/utf8>> -> true; <<"g"/utf8>> -> true; <<"h"/utf8>> -> true; <<"i"/utf8>> -> true; <<"j"/utf8>> -> true; <<"k"/utf8>> -> true; <<"l"/utf8>> -> true; <<"m"/utf8>> -> true; <<"n"/utf8>> -> true; <<"o"/utf8>> -> true; <<"p"/utf8>> -> true; <<"q"/utf8>> -> true; <<"r"/utf8>> -> true; <<"s"/utf8>> -> true; <<"t"/utf8>> -> true; <<"u"/utf8>> -> true; <<"v"/utf8>> -> true; <<"w"/utf8>> -> true; <<"x"/utf8>> -> true; <<"y"/utf8>> -> true; <<"z"/utf8>> -> true; <<"_"/utf8>> -> true; <<"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. -spec similar_identifier_string(binary()) -> {ok, binary()} | {error, nil}. similar_identifier_string(String) -> Proposal = begin _pipe = gleam@string:trim(String), _pipe@1 = justin:snake_case(_pipe), _pipe@2 = gleam@string:to_graphemes(_pipe@1), _pipe@3 = gleam@list:drop_while( _pipe@2, fun(G) -> (G =:= <<"_"/utf8>>) orelse is_digit(G) end ), _pipe@4 = gleam@list:filter(_pipe@3, fun is_identifier_char/1), gleam@string:join(_pipe@4, <<""/utf8>>) end, case Proposal of <<""/utf8>> -> {error, nil}; _ -> {ok, Proposal} end.