Current section
Files
Jump to
Current section
Files
src/glenv.erl
-module(glenv).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([load/2]).
-export_type([type/0, env_error/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(
" glenv is a library for type-sfe environment variable access.\n"
"\n"
).
-type type() :: bool | float | int | string.
-type env_error() :: {missing_key_error, binary()} |
{invalid_env_value_error, binary(), type()} |
{definition_mismatch_error, list(gleam@dynamic@decode:decode_error())}.
-file("src/glenv.gleam", 113).
-spec do_parse({binary(), type()}, binary()) -> {ok,
{binary(), gleam@dynamic:dynamic_()}} |
{error, env_error()}.
do_parse(Definition, Value) ->
case Definition of
{Key, bool} ->
case glenv@internal@parse:bool(Key, Value) of
{ok, Resolution} ->
{ok, Resolution};
{error, _} ->
{error, {invalid_env_value_error, Key, bool}}
end;
{Key@1, float} ->
case glenv@internal@parse:float(Key@1, Value) of
{ok, Resolution@1} ->
{ok, Resolution@1};
{error, _} ->
{error, {invalid_env_value_error, Key@1, float}}
end;
{Key@2, int} ->
case glenv@internal@parse:int(Key@2, Value) of
{ok, Resolution@2} ->
{ok, Resolution@2};
{error, _} ->
{error, {invalid_env_value_error, Key@2, int}}
end;
{Key@3, string} ->
case glenv@internal@parse:string(Key@3, Value) of
{ok, Resolution@3} ->
{ok, Resolution@3};
{error, _} ->
{error, {invalid_env_value_error, Key@3, string}}
end
end.
-file("src/glenv.gleam", 100).
-spec parse(list({binary(), type()})) -> {ok,
list({binary(), gleam@dynamic:dynamic_()})} |
{error, env_error()}.
parse(Definitions) ->
Env = envoy_ffi:all(),
gleam@list:try_map(
Definitions,
fun(Definition) ->
Normalized_definition = {string:uppercase(
erlang:element(1, Definition)
),
erlang:element(2, Definition)},
case gleam_stdlib:map_get(
Env,
erlang:element(1, Normalized_definition)
) of
{ok, Value} ->
do_parse(Normalized_definition, Value);
{error, _} ->
{error,
{missing_key_error,
erlang:element(1, Normalized_definition)}}
end
end
).
-file("src/glenv.gleam", 81).
?DOC(
" Load parses the environment variables and returns a Result containing the environment.\n"
" Takes a decoder from the gleam/decode library and a list of definitions.\n"
" \n"
" ## Examples\n"
"\n"
" ```gleam\n"
" type Env {\n"
" Env(hello: String, foo: Float, count: Int, is_on: Bool)\n"
" }\n"
"\n"
" let definitions = [\n"
" #(\"HELLO\", glenv.String),\n"
" #(\"FOO\", glenv.Float),\n"
" #(\"COUNT\", glenv.Int),\n"
" #(\"IS_ON\", glenv.Bool),\n"
" ]\n"
"\n"
" let decoder =\n"
" decode.into({\n"
" use hello <- decode.parameter\n"
" use foo <- decode.parameter\n"
" use count <- decode.parameter\n"
" use is_on <- decode.parameter\n"
"\n"
" Env(hello: hello, foo: foo, count: count, is_on: is_on)\n"
" })\n"
" |> decode.field(\"HELLO\", decode.string)\n"
" |> decode.field(\"FOO\", decode.float)\n"
" |> decode.field(\"COUNT\", decode.int)\n"
" |> decode.field(\"IS_ON\", decode.bool)\n"
"\n"
" let assert Ok(env) = glenv.load(decoder, definitions)\n"
"\n"
" env.hello // \"world\"\n"
" env.foo // 1.0\n"
" env.count // 1\n"
" env.is_on // True\n"
" ```\n"
).
-spec load(gleam@dynamic@decode:decoder(EYE), list({binary(), type()})) -> {ok,
EYE} |
{error, env_error()}.
load(Decoder, Definitions) ->
gleam@result:'try'(
parse(Definitions),
fun(Parsed_env) ->
case begin
_pipe = Parsed_env,
_pipe@1 = maps:from_list(_pipe),
_pipe@2 = gleam_stdlib:identity(_pipe@1),
gleam@dynamic@decode:run(_pipe@2, Decoder)
end of
{ok, Env} ->
{ok, Env};
{error, Err} ->
{error, {definition_mismatch_error, Err}}
end
end
).