-module(embeds@env). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([string/1, generate/1, get_variables/3, list/2, default_parse/2, typed_parse/1, typed_parse_fallback/2, int/1, float/1, bool/1, main/0]). -export_type([options/0]). -type options() :: {options, binary(), binary(), fun((binary(), binary()) -> embeds@generate:code()), binary(), gleam@option:option(gleam@regex:regex())}. -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 402). -spec chop_prefix(binary(), binary()) -> {ok, binary()} | {error, nil}. chop_prefix(String, Prefix) -> case {gleam@string:pop_grapheme(String), gleam@string:pop_grapheme(Prefix)} of {{ok, {Ch1, String@1}}, {ok, {Ch2, Prefix@1}}} when Ch1 =:= Ch2 -> chop_prefix(String@1, Prefix@1); {_, {error, nil}} -> {ok, String}; {_, _} -> {error, nil} end. -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 296). -spec string(binary()) -> embeds@generate:code(). string(Value) -> {constant, gleam@string:inspect(Value)}. -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 85). -spec generate(options()) -> {ok, nil} | {error, list(embeds@generate:error())}. generate(Options) -> embeds@generate:guard_gleam_project( fun() -> {options, Module, Header, Parse, Prefix, Regex} = Options, Defs = get_variables(Module, Prefix, Regex), Wrapped_parse = fun(Name, Code) -> case Code of {text, Text} -> Parse(Name, Text); {binary, _} -> skip end end, embeds@generate:generate(Defs, Header, Wrapped_parse, true) end ). -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 367). -spec get_variables( binary(), binary(), gleam@option:option(gleam@regex:regex()) ) -> list(embeds@generate:definition()). get_variables(Module, Prefix, Regex) -> gleam@list:filter_map( maps:to_list(envoy_ffi:all()), fun(_use0) -> {Key, Value} = _use0, gleam@result:'try'( chop_prefix(Key, Prefix), fun(Var_name) -> gleam@result:'try'(case Regex of {some, Regex@1} -> case gleam@regex:scan(Regex@1, Var_name) of [{match, _, [{some, Matched} | _]} | _] -> {ok, Matched}; [_ | _] -> {ok, Var_name}; [] -> {error, nil} end; none -> {ok, Var_name} end, fun(Var_name@1) -> Var_name@2 = embeds@generate:to_gleam_identifier( Var_name@1 ), {ok, {definition, Key, fun() -> {ok, {text, Value}} end, 0, Module, Var_name@2}} end) end ) end ). -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 335). -spec list(fun((binary()) -> embeds@generate:code()), binary()) -> fun((binary()) -> embeds@generate:code()). list(Item_parser, Separator) -> fun(Value) -> List = gleam@string:split(Value, Separator), Result = (gleam@list:try_fold( List, {[], true}, fun(_use0, Value@1) -> {Parts, Is_const} = _use0, case Item_parser(gleam@string:trim(Value@1)) of skip -> {ok, {Parts, Is_const}}; {generate_error, Error} -> {error, Error}; {constant, Code} -> {ok, {[Code | Parts], Is_const}}; {function_body, Code@1} -> {ok, {[Code@1 | Parts], false}} end end )), case Result of {ok, {Parts@1, Is_const@1}} -> Code@2 = gleam@string:inspect(lists:reverse(Parts@1)), case Is_const@1 of true -> {constant, Code@2}; false -> {function_body, Code@2} end; {error, Err} -> {generate_error, Err} end end. -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 55). -spec default_parse(binary(), binary()) -> embeds@generate:code(). default_parse(_, Value) -> {constant, gleam@string:inspect(Value)}. -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 267). -spec typed_parse(list({binary(), fun((binary()) -> embeds@generate:code())})) -> fun((binary(), binary()) -> embeds@generate:code()). typed_parse(Definitions) -> fun(Key, Value) -> case gleam@list:key_find(Definitions, Key) of {ok, Parser} -> Parser(gleam@string:trim(Value)); {error, nil} -> skip end end. -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 283). -spec typed_parse_fallback( list({binary(), fun((binary()) -> embeds@generate:code())}), fun((binary(), binary()) -> embeds@generate:code()) ) -> fun((binary(), binary()) -> embeds@generate:code()). typed_parse_fallback(Definitions, Fallback) -> fun(Key, Value) -> case gleam@list:key_find(Definitions, Key) of {ok, Parser} -> Parser(gleam@string:trim(Value)); {error, nil} -> Fallback(Key, Value) end end. -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 301). -spec int(binary()) -> embeds@generate:code(). int(Value) -> embeds@generate:result_to_const( (gleam@result:map( begin _pipe = gleam@int:parse(Value), gleam@result:replace_error( _pipe, <<"Invalid integer: "/utf8, Value/binary>> ) end, fun(N) -> gleam@string:inspect(N) end )) ). -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 313). -spec float(binary()) -> embeds@generate:code(). float(Value) -> embeds@generate:result_to_const( (gleam@result:map( begin _pipe = gleam@float:parse(Value), gleam@result:replace_error( _pipe, <<"Invalid number: "/utf8, Value/binary>> ) end, fun(N) -> gleam@string:inspect(N) end )) ). -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 324). -spec bool(binary()) -> embeds@generate:code(). bool(Value) -> Sanitized = gleam@string:trim(gleam@string:lowercase(Value)), Bool = case Sanitized of <<"true"/utf8>> -> true; <<"yes"/utf8>> -> true; <<"on"/utf8>> -> true; <<"1"/utf8>> -> true; _ -> false end, {constant, gleam@string:inspect(Bool)}. -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 191). -spec parse_definitions(list(binary())) -> {ok, list({binary(), fun((binary()) -> embeds@generate:code())})} | {error, list(embeds@generate:error())}. parse_definitions(Args) -> embeds@internal:traverse_map( Args, fun(Arg) -> case gleam@string:split(Arg, <<":"/utf8>>) of [Name, Type_name] -> Name@1 = gleam@string:trim(Name), case gleam@string:trim(gleam@string:lowercase(Type_name)) of <<"bool"/utf8>> -> {ok, {Name@1, fun bool/1}}; <<"int"/utf8>> -> {ok, {Name@1, fun int/1}}; <<"float"/utf8>> -> {ok, {Name@1, fun float/1}}; <<"string"/utf8>> -> {ok, {Name@1, fun string/1}}; _ -> {error, [{invalid_argument, <<""/utf8>>, Arg, <<"Invalid type name: "/utf8, Type_name/binary>>}]} end; _ -> {error, [{invalid_argument, <<""/utf8>>, Arg, <<"Invalid type definition"/utf8>>}]} end end ). -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 120). -spec generate_cmd() -> glint:command(nil). generate_cmd() -> glint:command_help( <<<<<<<<"Generate Gleam modules containing String constants of whitelisted environment variables.\n\n\n"/utf8, "By default, environment variables starting with `BUILD_' will be included, and a module called build_env will be generated.\n\n"/utf8>>/binary, "The generted constants have this prefix stripped.\n\n\n"/utf8>>/binary, "You can optionally provide a list of NAME:TYPE pairs to generate constants of other types instead.\n\n"/utf8>>/binary, "Valid types names are: int, float, bool, string"/utf8>>, fun() -> glint:flag( begin _pipe = glint:string_flag(<<"module"/utf8>>), _pipe@1 = glint:flag_default(_pipe, <<"build_env"/utf8>>), glint:flag_help( _pipe@1, <<"Name of the generated Gleam module (default: build_env)"/utf8>> ) end, fun(Module_name) -> glint:flag( begin _pipe@2 = glint:string_flag(<<"prefix"/utf8>>), _pipe@3 = glint:flag_default( _pipe@2, <<"BUILD_"/utf8>> ), glint:flag_help( _pipe@3, <<"Only environment variables matching this prefix will be included, and the prefix will be stripped from their name. (default: BUILD_)"/utf8>> ) end, fun(Prefix) -> glint:flag( begin _pipe@4 = glint:string_flag( <<"filter"/utf8>> ), glint:flag_help( _pipe@4, <<"Use a regular expression to match environment variables. If a capture group exists, it will be used as the variable name. If both prefix and regex are given, the prefix will be stripped first."/utf8>> ) end, fun(Filter) -> glint:command( fun(_, Args, Flags) -> _assert_subject = Module_name(Flags), {ok, Module} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"embeds/env"/utf8>>, function => <<"generate_cmd"/utf8>>, line => 154} ) end, _assert_subject@1 = Prefix(Flags), {ok, Prefix@1} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error( #{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail@1, module => <<"embeds/env"/utf8>>, function => <<"generate_cmd"/utf8>>, line => 155} ) end, Filter@1 = begin _pipe@5 = Filter(Flags), gleam@option:from_result( _pipe@5 ) end, Result = (gleam@result:'try'( case Filter@1 of {some, Filter@2} -> case gleam@regex:from_string( Filter@2 ) of {ok, Regex} -> {ok, {some, Regex}}; {error, {compile_error, Error, _}} -> {error, [{invalid_argument, <<"filter"/utf8>>, Filter@2, Error}]} end; none -> {ok, none} end, fun(Regex@1) -> gleam@result:'try'( parse_definitions(Args), fun(Definitions) -> Options = {options, embeds@generate:to_gleam_module_name( Module ), <<"//// Generated by `embeds`, manual edits are futile"/utf8>>, typed_parse_fallback( Definitions, fun default_parse/2 ), Prefix@1, Regex@1}, generate(Options) end ) end )), case Result of {ok, nil} -> nil; {error, Errs} -> gleam@io:println_error( embeds@generate:describe_errors( Errs ) ) end, nil end ) end ) end ) end ) end ). -file("/home/arkan/Projects/private/embeds/src/embeds/env.gleam", 113). -spec main() -> nil. main() -> _pipe = glint:new(), _pipe@1 = glint:pretty_help(_pipe, glint:default_pretty_help()), _pipe@2 = glint:add(_pipe@1, [], generate_cmd()), glint:run(_pipe@2, erlang:element(4, argv:load())).