aboutsummaryrefslogtreecommitdiff
path: root/aoc2023/build/packages/glint/src
diff options
context:
space:
mode:
Diffstat (limited to 'aoc2023/build/packages/glint/src')
-rw-r--r--aoc2023/build/packages/glint/src/glint.app.src13
-rw-r--r--aoc2023/build/packages/glint/src/glint.erl513
-rw-r--r--aoc2023/build/packages/glint/src/glint.gleam588
-rw-r--r--aoc2023/build/packages/glint/src/glint/flag.gleam478
-rw-r--r--aoc2023/build/packages/glint/src/glint/flag/constraint.gleam66
-rw-r--r--aoc2023/build/packages/glint/src/glint@flag.erl523
-rw-r--r--aoc2023/build/packages/glint/src/glint@flag@constraint.erl68
7 files changed, 0 insertions, 2249 deletions
diff --git a/aoc2023/build/packages/glint/src/glint.app.src b/aoc2023/build/packages/glint/src/glint.app.src
deleted file mode 100644
index 7eb7649..0000000
--- a/aoc2023/build/packages/glint/src/glint.app.src
+++ /dev/null
@@ -1,13 +0,0 @@
-{application, glint, [
- {vsn, "0.13.0"},
- {applications, [gleam_community_ansi,
- gleam_community_colour,
- gleam_stdlib,
- gleeunit,
- snag]},
- {description, "Gleam command line argument parsing with basic flag support."},
- {modules, [glint,
- glint@flag,
- glint@flag@constraint]},
- {registered, []}
-]}.
diff --git a/aoc2023/build/packages/glint/src/glint.erl b/aoc2023/build/packages/glint/src/glint.erl
deleted file mode 100644
index 0501cc6..0000000
--- a/aoc2023/build/packages/glint/src/glint.erl
+++ /dev/null
@@ -1,513 +0,0 @@
--module(glint).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([with_config/2, with_pretty_help/2, without_pretty_help/1, with_name/2, new/0, command/1, description/2, flag/3, flag_tuple/2, flags/2, global_flag/3, global_flag_tuple/2, global_flags/2, default_pretty_help/0, add/3, help_flag/0, execute/2, run_and_handle/3, run/2, add_command_from_stub/2]).
--export_type([config/0, pretty_help/0, glint/1, command/1, command_input/0, command_node/1, out/1, stub/1]).
-
--type config() :: {config,
- gleam@option:option(pretty_help()),
- gleam@option:option(binary())}.
-
--type pretty_help() :: {pretty_help,
- gleam_community@colour:colour(),
- gleam_community@colour:colour(),
- gleam_community@colour:colour()}.
-
--opaque glint(GHR) :: {glint,
- config(),
- command_node(GHR),
- gleam@map:map_(binary(), glint@flag:flag())}.
-
--opaque command(GHS) :: {command,
- fun((command_input()) -> GHS),
- gleam@map:map_(binary(), glint@flag:flag()),
- binary()}.
-
--type command_input() :: {command_input,
- list(binary()),
- gleam@map:map_(binary(), glint@flag:flag())}.
-
--type command_node(GHT) :: {command_node,
- gleam@option:option(command(GHT)),
- gleam@map:map_(binary(), command_node(GHT))}.
-
--type out(GHU) :: {out, GHU} | {help, binary()}.
-
--type stub(GHV) :: {stub,
- list(binary()),
- fun((command_input()) -> GHV),
- list({binary(), glint@flag:flag()}),
- binary()}.
-
--spec with_config(glint(GIA), config()) -> glint(GIA).
-with_config(Glint, Config) ->
- erlang:setelement(2, Glint, Config).
-
--spec with_pretty_help(glint(GID), pretty_help()) -> glint(GID).
-with_pretty_help(Glint, Pretty) ->
- _pipe = erlang:setelement(2, erlang:element(2, Glint), {some, Pretty}),
- with_config(Glint, _pipe).
-
--spec without_pretty_help(glint(GIG)) -> glint(GIG).
-without_pretty_help(Glint) ->
- _pipe = erlang:setelement(2, erlang:element(2, Glint), none),
- with_config(Glint, _pipe).
-
--spec with_name(glint(GIJ), binary()) -> glint(GIJ).
-with_name(Glint, Name) ->
- _pipe = erlang:setelement(3, erlang:element(2, Glint), {some, Name}),
- with_config(Glint, _pipe).
-
--spec empty_command() -> command_node(any()).
-empty_command() ->
- {command_node, none, gleam@map:new()}.
-
--spec new() -> glint(any()).
-new() ->
- {glint, {config, none, none}, empty_command(), gleam@map:new()}.
-
--spec do_add(command_node(GIT), list(binary()), command(GIT)) -> command_node(GIT).
-do_add(Root, Path, Contents) ->
- case Path of
- [] ->
- erlang:setelement(2, Root, {some, Contents});
-
- [X | Xs] ->
- erlang:setelement(
- 3,
- Root,
- (gleam@map:update(
- erlang:element(3, Root),
- X,
- fun(Node) -> _pipe = Node,
- _pipe@1 = gleam@option:lazy_unwrap(
- _pipe,
- fun empty_command/0
- ),
- do_add(_pipe@1, Xs, Contents) end
- ))
- )
- end.
-
--spec command(fun((command_input()) -> GJC)) -> command(GJC).
-command(Runner) ->
- {command, Runner, gleam@map:new(), <<""/utf8>>}.
-
--spec description(command(GJF), binary()) -> command(GJF).
-description(Cmd, Description) ->
- erlang:setelement(4, Cmd, Description).
-
--spec flag(command(GJI), binary(), glint@flag:flag_builder(any())) -> command(GJI).
-flag(Cmd, Key, Flag) ->
- erlang:setelement(
- 3,
- Cmd,
- gleam@map:insert(erlang:element(3, Cmd), Key, glint@flag:build(Flag))
- ).
-
--spec flag_tuple(command(GJN), {binary(), glint@flag:flag_builder(any())}) -> command(GJN).
-flag_tuple(Cmd, Tup) ->
- flag(Cmd, erlang:element(1, Tup), erlang:element(2, Tup)).
-
--spec flags(command(GJS), list({binary(), glint@flag:flag()})) -> command(GJS).
-flags(Cmd, Flags) ->
- gleam@list:fold(
- Flags,
- Cmd,
- fun(Cmd@1, _use1) ->
- {Key, Flag} = _use1,
- erlang:setelement(
- 3,
- Cmd@1,
- gleam@map:insert(erlang:element(3, Cmd@1), Key, Flag)
- )
- end
- ).
-
--spec global_flag(glint(GJW), binary(), glint@flag:flag_builder(any())) -> glint(GJW).
-global_flag(Glint, Key, Flag) ->
- erlang:setelement(
- 4,
- Glint,
- gleam@map:insert(erlang:element(4, Glint), Key, glint@flag:build(Flag))
- ).
-
--spec global_flag_tuple(glint(GKB), {binary(), glint@flag:flag_builder(any())}) -> glint(GKB).
-global_flag_tuple(Glint, Tup) ->
- global_flag(Glint, erlang:element(1, Tup), erlang:element(2, Tup)).
-
--spec global_flags(glint(GKG), list({binary(), glint@flag:flag()})) -> glint(GKG).
-global_flags(Glint, Flags) ->
- erlang:setelement(
- 4,
- Glint,
- (gleam@list:fold(
- Flags,
- erlang:element(4, Glint),
- fun(Acc, Tup) ->
- gleam@map:insert(
- Acc,
- erlang:element(1, Tup),
- erlang:element(2, Tup)
- )
- end
- ))
- ).
-
--spec execute_root(
- command_node(GKU),
- gleam@map:map_(binary(), glint@flag:flag()),
- list(binary()),
- list(binary())
-) -> {ok, out(GKU)} | {error, snag:snag()}.
-execute_root(Cmd, Global_flags, Args, Flag_inputs) ->
- _pipe@3 = case erlang:element(2, Cmd) of
- {some, Contents} ->
- gleam@result:'try'(
- gleam@list:try_fold(
- Flag_inputs,
- gleam@map:merge(Global_flags, erlang:element(3, Contents)),
- fun glint@flag:update_flags/2
- ),
- fun(New_flags) -> _pipe = {command_input, Args, New_flags},
- _pipe@1 = (erlang:element(2, Contents))(_pipe),
- _pipe@2 = {out, _pipe@1},
- {ok, _pipe@2} end
- );
-
- none ->
- snag:error(<<"command not found"/utf8>>)
- end,
- snag:context(_pipe@3, <<"failed to run command"/utf8>>).
-
--spec default_pretty_help() -> pretty_help().
-default_pretty_help() ->
- _assert_subject = gleam_community@colour:from_rgb255(182, 255, 234),
- {ok, Usage_colour} = case _assert_subject of
- {ok, _} -> _assert_subject;
- _assert_fail ->
- erlang:error(#{gleam_error => let_assert,
- message => <<"Assertion pattern match failed"/utf8>>,
- value => _assert_fail,
- module => <<"glint"/utf8>>,
- function => <<"default_pretty_help"/utf8>>,
- line => 404})
- end,
- _assert_subject@1 = gleam_community@colour:from_rgb255(255, 175, 243),
- {ok, Flags_colour} = case _assert_subject@1 of
- {ok, _} -> _assert_subject@1;
- _assert_fail@1 ->
- erlang:error(#{gleam_error => let_assert,
- message => <<"Assertion pattern match failed"/utf8>>,
- value => _assert_fail@1,
- module => <<"glint"/utf8>>,
- function => <<"default_pretty_help"/utf8>>,
- line => 405})
- end,
- _assert_subject@2 = gleam_community@colour:from_rgb255(252, 226, 174),
- {ok, Subcommands_colour} = case _assert_subject@2 of
- {ok, _} -> _assert_subject@2;
- _assert_fail@2 ->
- erlang:error(#{gleam_error => let_assert,
- message => <<"Assertion pattern match failed"/utf8>>,
- value => _assert_fail@2,
- module => <<"glint"/utf8>>,
- function => <<"default_pretty_help"/utf8>>,
- line => 406})
- end,
- {pretty_help, Usage_colour, Flags_colour, Subcommands_colour}.
-
--spec is_not_empty(binary()) -> boolean().
-is_not_empty(S) ->
- S /= <<""/utf8>>.
-
--spec sanitize_path(list(binary())) -> list(binary()).
-sanitize_path(Path) ->
- _pipe = Path,
- _pipe@1 = gleam@list:map(_pipe, fun gleam@string:trim/1),
- gleam@list:filter(_pipe@1, fun is_not_empty/1).
-
--spec add(glint(GIO), list(binary()), command(GIO)) -> glint(GIO).
-add(Glint, Path, Contents) ->
- erlang:setelement(
- 3,
- Glint,
- begin
- _pipe = Path,
- _pipe@1 = sanitize_path(_pipe),
- do_add(erlang:element(3, Glint), _pipe@1, Contents)
- end
- ).
-
--spec help_flag() -> binary().
-help_flag() ->
- <<(<<"--"/utf8>>)/binary, "help"/utf8>>.
-
--spec wrap_with_space(binary()) -> binary().
-wrap_with_space(S) ->
- case S of
- <<""/utf8>> ->
- <<" "/utf8>>;
-
- _ ->
- <<<<" "/utf8, S/binary>>/binary, " "/utf8>>
- end.
-
--spec subcommand_help(binary(), command_node(any())) -> binary().
-subcommand_help(Name, Cmd) ->
- case erlang:element(2, Cmd) of
- none ->
- Name;
-
- {some, Contents} ->
- <<<<Name/binary, "\t\t"/utf8>>/binary,
- (erlang:element(4, Contents))/binary>>
- end.
-
--spec subcommands_help(gleam@map:map_(binary(), command_node(any()))) -> binary().
-subcommands_help(Cmds) ->
- _pipe = Cmds,
- _pipe@1 = gleam@map:map_values(_pipe, fun subcommand_help/2),
- _pipe@2 = gleam@map:values(_pipe@1),
- _pipe@3 = gleam@list:sort(_pipe@2, fun gleam@string:compare/2),
- gleam@string:join(_pipe@3, <<"\n\t"/utf8>>).
-
--spec heading_style(binary(), gleam_community@colour:colour()) -> binary().
-heading_style(Heading, Colour) ->
- _pipe = Heading,
- _pipe@1 = gleam_community@ansi:bold(_pipe),
- _pipe@2 = gleam_community@ansi:underline(_pipe@1),
- _pipe@3 = gleam_community@ansi:italic(_pipe@2),
- _pipe@4 = gleam_community@ansi:hex(
- _pipe@3,
- gleam_community@colour:to_rgb_hex(Colour)
- ),
- gleam_community@ansi:reset(_pipe@4).
-
--spec usage_help(
- binary(),
- gleam@map:map_(binary(), glint@flag:flag()),
- config()
-) -> binary().
-usage_help(Cmd_name, Flags, Config) ->
- App_name = gleam@option:unwrap(
- erlang:element(3, Config),
- <<"gleam run"/utf8>>
- ),
- Flags@1 = begin
- _pipe = Flags,
- _pipe@1 = gleam@map:to_list(_pipe),
- _pipe@2 = gleam@list:map(_pipe@1, fun glint@flag:flag_type_help/1),
- gleam@list:sort(_pipe@2, fun gleam@string:compare/2)
- end,
- Flag_sb = case Flags@1 of
- [] ->
- gleam@string_builder:new();
-
- _ ->
- _pipe@3 = Flags@1,
- _pipe@4 = gleam@list:intersperse(_pipe@3, <<" "/utf8>>),
- _pipe@5 = gleam@string_builder:from_strings(_pipe@4),
- _pipe@6 = gleam@string_builder:prepend(_pipe@5, <<" [ "/utf8>>),
- gleam@string_builder:append(_pipe@6, <<" ]"/utf8>>)
- end,
- _pipe@7 = [App_name, wrap_with_space(Cmd_name), <<"[ ARGS ]"/utf8>>],
- _pipe@8 = gleam@string_builder:from_strings(_pipe@7),
- _pipe@9 = gleam@string_builder:append_builder(_pipe@8, Flag_sb),
- _pipe@12 = gleam@string_builder:prepend(
- _pipe@9,
- <<(begin
- _pipe@10 = erlang:element(2, Config),
- _pipe@11 = gleam@option:map(
- _pipe@10,
- fun(Styling) ->
- heading_style(
- <<"USAGE:"/utf8>>,
- erlang:element(2, Styling)
- )
- end
- ),
- gleam@option:unwrap(_pipe@11, <<"USAGE:"/utf8>>)
- end)/binary,
- "\n\t"/utf8>>
- ),
- gleam@string_builder:to_string(_pipe@12).
-
--spec cmd_help(
- list(binary()),
- command_node(any()),
- config(),
- gleam@map:map_(binary(), glint@flag:flag())
-) -> binary().
-cmd_help(Path, Cmd, Config, Global_flags) ->
- Name = begin
- _pipe = Path,
- _pipe@1 = gleam@list:reverse(_pipe),
- gleam@string:join(_pipe@1, <<" "/utf8>>)
- end,
- Flags = begin
- _pipe@2 = gleam@option:map(
- erlang:element(2, Cmd),
- fun(Contents) -> erlang:element(3, Contents) end
- ),
- _pipe@3 = gleam@option:lazy_unwrap(_pipe@2, fun gleam@map:new/0),
- gleam@map:merge(Global_flags, _pipe@3)
- end,
- Flags_help_body = <<<<(begin
- _pipe@4 = erlang:element(2, Config),
- _pipe@5 = gleam@option:map(
- _pipe@4,
- fun(P) ->
- heading_style(<<"FLAGS:"/utf8>>, erlang:element(3, P))
- end
- ),
- gleam@option:unwrap(_pipe@5, <<"FLAGS:"/utf8>>)
- end)/binary,
- "\n\t"/utf8>>/binary,
- (gleam@string:join(
- gleam@list:sort(
- [<<"--help\t\t\tPrint help information"/utf8>> |
- glint@flag:flags_help(Flags)],
- fun gleam@string:compare/2
- ),
- <<"\n\t"/utf8>>
- ))/binary>>,
- Usage = usage_help(Name, Flags, Config),
- Description = begin
- _pipe@6 = erlang:element(2, Cmd),
- _pipe@7 = gleam@option:map(
- _pipe@6,
- fun(Contents@1) -> erlang:element(4, Contents@1) end
- ),
- gleam@option:unwrap(_pipe@7, <<""/utf8>>)
- end,
- Header_items = begin
- _pipe@8 = [Name, Description],
- _pipe@9 = gleam@list:filter(_pipe@8, fun is_not_empty/1),
- gleam@string:join(_pipe@9, <<"\n"/utf8>>)
- end,
- Subcommands = case subcommands_help(erlang:element(3, Cmd)) of
- <<""/utf8>> ->
- <<""/utf8>>;
-
- Subcommands_help_body ->
- <<<<(begin
- _pipe@10 = erlang:element(2, Config),
- _pipe@11 = gleam@option:map(
- _pipe@10,
- fun(P@1) ->
- heading_style(
- <<"SUBCOMMANDS:"/utf8>>,
- erlang:element(4, P@1)
- )
- end
- ),
- gleam@option:unwrap(_pipe@11, <<"SUBCOMMANDS:"/utf8>>)
- end)/binary,
- "\n\t"/utf8>>/binary,
- Subcommands_help_body/binary>>
- end,
- _pipe@12 = [Header_items, Usage, Flags_help_body, Subcommands],
- _pipe@13 = gleam@list:filter(_pipe@12, fun is_not_empty/1),
- gleam@string:join(_pipe@13, <<"\n\n"/utf8>>).
-
--spec do_execute(
- command_node(GKO),
- config(),
- gleam@map:map_(binary(), glint@flag:flag()),
- list(binary()),
- list(binary()),
- boolean(),
- list(binary())
-) -> {ok, out(GKO)} | {error, snag:snag()}.
-do_execute(Cmd, Config, Global_flags, Args, Flags, Help, Command_path) ->
- case Args of
- [] when Help ->
- _pipe = Command_path,
- _pipe@1 = cmd_help(_pipe, Cmd, Config, Global_flags),
- _pipe@2 = {help, _pipe@1},
- {ok, _pipe@2};
-
- [] ->
- execute_root(Cmd, Global_flags, [], Flags);
-
- [Arg | Rest] ->
- case gleam@map:get(erlang:element(3, Cmd), Arg) of
- {ok, Cmd@1} ->
- do_execute(
- Cmd@1,
- Config,
- Global_flags,
- Rest,
- Flags,
- Help,
- [Arg | Command_path]
- );
-
- _ when Help ->
- _pipe@3 = Command_path,
- _pipe@4 = cmd_help(_pipe@3, Cmd, Config, Global_flags),
- _pipe@5 = {help, _pipe@4},
- {ok, _pipe@5};
-
- _ ->
- execute_root(Cmd, Global_flags, Args, Flags)
- end
- end.
-
--spec execute(glint(GKK), list(binary())) -> {ok, out(GKK)} |
- {error, snag:snag()}.
-execute(Glint, Args) ->
- Help_flag = help_flag(),
- {Help, Args@2} = case gleam@list:pop(Args, fun(S) -> S =:= Help_flag end) of
- {ok, {_, Args@1}} ->
- {true, Args@1};
-
- _ ->
- {false, Args}
- end,
- {Flags, Args@3} = gleam@list:partition(
- Args@2,
- fun(_capture) -> gleam@string:starts_with(_capture, <<"--"/utf8>>) end
- ),
- do_execute(
- erlang:element(3, Glint),
- erlang:element(2, Glint),
- erlang:element(4, Glint),
- Args@3,
- Flags,
- Help,
- []
- ).
-
--spec run_and_handle(glint(GLC), list(binary()), fun((GLC) -> any())) -> nil.
-run_and_handle(Glint, Args, Handle) ->
- case execute(Glint, Args) of
- {error, Err} ->
- _pipe = Err,
- _pipe@1 = snag:pretty_print(_pipe),
- gleam@io:println(_pipe@1);
-
- {ok, {help, Help}} ->
- gleam@io:println(Help);
-
- {ok, {out, Out}} ->
- Handle(Out),
- nil
- end.
-
--spec run(glint(any()), list(binary())) -> nil.
-run(Glint, Args) ->
- run_and_handle(Glint, Args, gleam@function:constant(nil)).
-
--spec add_command_from_stub(glint(GLP), stub(GLP)) -> glint(GLP).
-add_command_from_stub(Glint, Stub) ->
- add(
- Glint,
- erlang:element(2, Stub),
- begin
- _pipe = command(erlang:element(3, Stub)),
- _pipe@1 = flags(_pipe, erlang:element(4, Stub)),
- description(_pipe@1, erlang:element(5, Stub))
- end
- ).
diff --git a/aoc2023/build/packages/glint/src/glint.gleam b/aoc2023/build/packages/glint/src/glint.gleam
deleted file mode 100644
index b159016..0000000
--- a/aoc2023/build/packages/glint/src/glint.gleam
+++ /dev/null
@@ -1,588 +0,0 @@
-import gleam/map.{type Map}
-import gleam/option.{type Option, None, Some}
-import gleam/list
-import gleam/io
-import gleam/string
-import snag.{type Result}
-import glint/flag.{type Flag, type Map as FlagMap}
-import gleam/string_builder as sb
-import gleam_community/ansi
-import gleam_community/colour.{type Colour}
-import gleam/result
-import gleam/function
-
-// --- CONFIGURATION ---
-
-// -- CONFIGURATION: TYPES --
-
-/// Config for glint
-///
-pub type Config {
- Config(pretty_help: Option(PrettyHelp), name: Option(String))
-}
-
-/// PrettyHelp defines the header colours to be used when styling help text
-///
-pub type PrettyHelp {
- PrettyHelp(usage: Colour, flags: Colour, subcommands: Colour)
-}
-
-// -- CONFIGURATION: CONSTANTS --
-
-/// Default config
-///
-pub const default_config = Config(pretty_help: None, name: None)
-
-// -- CONFIGURATION: FUNCTIONS --
-
-/// Add the provided config to the existing command tree
-///
-pub fn with_config(glint: Glint(a), config: Config) -> Glint(a) {
- Glint(..glint, config: config)
-}
-
-/// Enable custom colours for help text headers
-/// For a pre-made colouring use `default_pretty_help()`
-///
-pub fn with_pretty_help(glint: Glint(a), pretty: PrettyHelp) -> Glint(a) {
- Config(..glint.config, pretty_help: Some(pretty))
- |> with_config(glint, _)
-}
-
-/// Disable custom colours for help text headers
-///
-pub fn without_pretty_help(glint: Glint(a)) -> Glint(a) {
- Config(..glint.config, pretty_help: None)
- |> with_config(glint, _)
-}
-
-pub fn with_name(glint: Glint(a), name: String) -> Glint(a) {
- Config(..glint.config, name: Some(name))
- |> with_config(glint, _)
-}
-
-// --- CORE ---
-
-// -- CORE: TYPES --
-
-/// Glint container type for config and commands
-///
-pub opaque type Glint(a) {
- Glint(config: Config, cmd: CommandNode(a), global_flags: FlagMap)
-}
-
-/// CommandNode contents
-///
-pub opaque type Command(a) {
- Command(do: Runner(a), flags: FlagMap, description: String)
-}
-
-/// Input type for `Runner`.
-///
-pub type CommandInput {
- CommandInput(args: List(String), flags: FlagMap)
-}
-
-/// Function type to be run by `glint`.
-///
-pub type Runner(a) =
- fn(CommandInput) -> a
-
-/// CommandNode tree representation.
-///
-type CommandNode(a) {
- CommandNode(
- contents: Option(Command(a)),
- subcommands: Map(String, CommandNode(a)),
- )
-}
-
-/// Ok type for command execution
-///
-pub type Out(a) {
- /// Container for the command return value
- Out(a)
- /// Container for the generated help string
- Help(String)
-}
-
-/// Result type for command execution
-///
-pub type CmdResult(a) =
- Result(Out(a))
-
-// -- CORE: BUILDER FUNCTIONS --
-
-/// Creates a new command tree.
-///
-pub fn new() -> Glint(a) {
- Glint(config: default_config, cmd: empty_command(), global_flags: map.new())
-}
-
-/// Adds a new command to be run at the specified path.
-///
-/// If the path is `[]`, the root command is set with the provided function and
-/// flags.
-///
-/// Note: all command paths are sanitized by stripping whitespace and removing any empty string elements.
-///
-pub fn add(
- to glint: Glint(a),
- at path: List(String),
- do contents: Command(a),
-) -> Glint(a) {
- Glint(
- ..glint,
- cmd: path
- |> sanitize_path
- |> do_add(to: glint.cmd, put: contents),
- )
-}
-
-/// Recursive traversal of the command tree to find where to puth the provided command
-///
-fn do_add(
- to root: CommandNode(a),
- at path: List(String),
- put contents: Command(a),
-) -> CommandNode(a) {
- case path {
- // update current command with provided contents
- [] -> CommandNode(..root, contents: Some(contents))
- // continue down the path, creating empty command nodes along the way
- [x, ..xs] ->
- CommandNode(
- ..root,
- subcommands: {
- use node <- map.update(root.subcommands, x)
- node
- |> option.lazy_unwrap(empty_command)
- |> do_add(xs, contents)
- },
- )
- }
-}
-
-/// Helper for initializing empty commands
-///
-fn empty_command() -> CommandNode(a) {
- CommandNode(contents: None, subcommands: map.new())
-}
-
-/// Trim each path element and remove any resulting empty strings.
-///
-fn sanitize_path(path: List(String)) -> List(String) {
- path
- |> list.map(string.trim)
- |> list.filter(is_not_empty)
-}
-
-/// Create a Command(a) from a Runner(a)
-///
-pub fn command(do runner: Runner(a)) -> Command(a) {
- Command(do: runner, flags: map.new(), description: "")
-}
-
-/// Attach a description to a Command(a)
-///
-pub fn description(cmd: Command(a), description: String) -> Command(a) {
- Command(..cmd, description: description)
-}
-
-/// add a `flag.Flag` to a `Command`
-///
-pub fn flag(
- cmd: Command(a),
- at key: String,
- of flag: flag.FlagBuilder(_),
-) -> Command(a) {
- Command(..cmd, flags: map.insert(cmd.flags, key, flag.build(flag)))
-}
-
-/// Add a `flag.Flag to a `Command` when the flag name and builder are bundled as a #(String, flag.FlagBuilder(a)).
-///
-/// This is merely a convenience function and calls `glint.flag` under the hood.
-///
-pub fn flag_tuple(
- cmd: Command(a),
- with tup: #(String, flag.FlagBuilder(_)),
-) -> Command(a) {
- flag(cmd, tup.0, tup.1)
-}
-
-/// Add multiple `Flag`s to a `Command`, note that this function uses `Flag` and not `FlagBuilder(_)`, so the user will need to call `flag.build` before providing the flags here.
-///
-/// It is recommended to call `glint.flag` instead.
-///
-pub fn flags(cmd: Command(a), with flags: List(#(String, Flag))) -> Command(a) {
- use cmd, #(key, flag) <- list.fold(flags, cmd)
- Command(..cmd, flags: map.insert(cmd.flags, key, flag))
-}
-
-/// Add global flags to the existing command tree
-///
-pub fn global_flag(
- glint: Glint(a),
- at key: String,
- of flag: flag.FlagBuilder(_),
-) -> Glint(a) {
- Glint(
- ..glint,
- global_flags: map.insert(glint.global_flags, key, flag.build(flag)),
- )
-}
-
-/// Add global flags to the existing command tree.
-///
-pub fn global_flag_tuple(
- glint: Glint(a),
- with tup: #(String, flag.FlagBuilder(_)),
-) -> Glint(a) {
- global_flag(glint, tup.0, tup.1)
-}
-
-/// Add global flags to the existing command tree.
-///
-/// Like `glint.flags`, this function requires `Flag`s insead of `FlagBuilder(_)`.
-///
-/// It is recommended to use `glint.global_flag` instead.
-///
-pub fn global_flags(glint: Glint(a), flags: List(#(String, Flag))) -> Glint(a) {
- Glint(
- ..glint,
- global_flags: {
- list.fold(
- flags,
- glint.global_flags,
- fn(acc, tup) { map.insert(acc, tup.0, tup.1) },
- )
- },
- )
-}
-
-// -- CORE: EXECUTION FUNCTIONS --
-
-/// Determines which command to run and executes it.
-///
-/// Sets any provided flags if necessary.
-///
-/// Each value prefixed with `--` is parsed as a flag.
-///
-/// This function does not print its output and is mainly intended for use within `glint` itself.
-/// If you would like to print or handle the output of a command please see the `run_and_handle` function.
-///
-pub fn execute(glint: Glint(a), args: List(String)) -> CmdResult(a) {
- // create help flag to check for
- let help_flag = help_flag()
-
- // check if help flag is present
- let #(help, args) = case list.pop(args, fn(s) { s == help_flag }) {
- Ok(#(_, args)) -> #(True, args)
- _ -> #(False, args)
- }
-
- // split flags out from the args list
- let #(flags, args) = list.partition(args, string.starts_with(_, flag.prefix))
-
- // search for command and execute
- do_execute(glint.cmd, glint.config, glint.global_flags, args, flags, help, [])
-}
-
-/// Find which command to execute and run it with computed flags and args
-///
-fn do_execute(
- cmd: CommandNode(a),
- config: Config,
- global_flags: FlagMap,
- args: List(String),
- flags: List(String),
- help: Bool,
- command_path: List(String),
-) -> CmdResult(a) {
- case args {
- // when there are no more available arguments
- // and help flag has been passed, generate help message
- [] if help ->
- command_path
- |> cmd_help(cmd, config, global_flags)
- |> Help
- |> Ok
-
- // when there are no more available arguments
- // run the current command
- [] -> execute_root(cmd, global_flags, [], flags)
-
- // when there are arguments remaining
- // check if the next one is a subcommand of the current command
- [arg, ..rest] ->
- case map.get(cmd.subcommands, arg) {
- // subcommand found, continue
- Ok(cmd) ->
- do_execute(
- cmd,
- config,
- global_flags,
- rest,
- flags,
- help,
- [arg, ..command_path],
- )
- // subcommand not found, but help flag has been passed
- // generate and return help message
- _ if help ->
- command_path
- |> cmd_help(cmd, config, global_flags)
- |> Help
- |> Ok
- // subcommand not found, but help flag has not been passed
- // execute the current command
- _ -> execute_root(cmd, global_flags, args, flags)
- }
- }
-}
-
-/// Executes the current root command.
-///
-fn execute_root(
- cmd: CommandNode(a),
- global_flags: FlagMap,
- args: List(String),
- flag_inputs: List(String),
-) -> CmdResult(a) {
- case cmd.contents {
- Some(contents) -> {
- use new_flags <- result.try(list.try_fold(
- over: flag_inputs,
- from: map.merge(global_flags, contents.flags),
- with: flag.update_flags,
- ))
- CommandInput(args, new_flags)
- |> contents.do
- |> Out
- |> Ok
- }
- None -> snag.error("command not found")
- }
- |> snag.context("failed to run command")
-}
-
-/// A wrapper for `execute` that prints any errors enountered or the help text if requested.
-/// This function ignores any value returned by the command that was run.
-/// If you would like to do something with the command output please see the run_and_handle function.
-///
-pub fn run(from glint: Glint(a), for args: List(String)) -> Nil {
- run_and_handle(from: glint, for: args, with: function.constant(Nil))
-}
-
-/// A wrapper for `execute` that prints any errors enountered or the help text if requested.
-/// This function calls the provided handler with the value returned by the command that was run.
-///
-pub fn run_and_handle(
- from glint: Glint(a),
- for args: List(String),
- with handle: fn(a) -> _,
-) -> Nil {
- case execute(glint, args) {
- Error(err) ->
- err
- |> snag.pretty_print
- |> io.println
- Ok(Help(help)) -> io.println(help)
- Ok(Out(out)) -> {
- handle(out)
- Nil
- }
- }
-}
-
-/// Default pretty help heading colouring
-/// mint (r: 182, g: 255, b: 234) colour for usage
-/// pink (r: 255, g: 175, b: 243) colour for flags
-/// buttercup (r: 252, g: 226, b: 174) colour for subcommands
-///
-pub fn default_pretty_help() -> PrettyHelp {
- let assert Ok(usage_colour) = colour.from_rgb255(182, 255, 234)
- let assert Ok(flags_colour) = colour.from_rgb255(255, 175, 243)
- let assert Ok(subcommands_colour) = colour.from_rgb255(252, 226, 174)
-
- PrettyHelp(
- usage: usage_colour,
- flags: flags_colour,
- subcommands: subcommands_colour,
- )
-}
-
-// constants for setting up sections of the help message
-const flags_heading = "FLAGS:"
-
-const subcommands_heading = "SUBCOMMANDS:"
-
-const usage_heading = "USAGE:"
-
-/// Helper for filtering out empty strings
-///
-fn is_not_empty(s: String) -> Bool {
- s != ""
-}
-
-const help_flag_name = "help"
-
-const help_flag_message = "--help\t\t\tPrint help information"
-
-/// Function to create the help flag string
-/// Exported for testing purposes only
-///
-pub fn help_flag() -> String {
- flag.prefix <> help_flag_name
-}
-
-// -- HELP: FUNCTIONS --
-
-fn wrap_with_space(s: String) -> String {
- case s {
- "" -> " "
- _ -> " " <> s <> " "
- }
-}
-
-/// generate the usage help string for a command
-fn usage_help(cmd_name: String, flags: FlagMap, config: Config) -> String {
- let app_name = option.unwrap(config.name, "gleam run")
- let flags =
- flags
- |> map.to_list
- |> list.map(flag.flag_type_help)
- |> list.sort(string.compare)
-
- let flag_sb = case flags {
- [] -> sb.new()
- _ ->
- flags
- |> list.intersperse(" ")
- |> sb.from_strings()
- |> sb.prepend(prefix: " [ ")
- |> sb.append(suffix: " ]")
- }
-
- [app_name, wrap_with_space(cmd_name), "[ ARGS ]"]
- |> sb.from_strings
- |> sb.append_builder(flag_sb)
- |> sb.prepend(
- config.pretty_help
- |> option.map(fn(styling) { heading_style(usage_heading, styling.usage) })
- |> option.unwrap(usage_heading) <> "\n\t",
- )
- |> sb.to_string
-}
-
-/// generate the help text for a command
-fn cmd_help(
- path: List(String),
- cmd: CommandNode(a),
- config: Config,
- global_flags: FlagMap,
-) -> String {
- // recreate the path of the current command
- // reverse the path because it is created by prepending each section as do_execute walks down the tree
- let name =
- path
- |> list.reverse
- |> string.join(" ")
-
- let flags =
- option.map(cmd.contents, fn(contents) { contents.flags })
- |> option.lazy_unwrap(map.new)
- |> map.merge(global_flags, _)
-
- let flags_help_body =
- config.pretty_help
- |> option.map(fn(p) { heading_style(flags_heading, p.flags) })
- |> option.unwrap(flags_heading) <> "\n\t" <> string.join(
- list.sort([help_flag_message, ..flag.flags_help(flags)], string.compare),
- "\n\t",
- )
-
- let usage = usage_help(name, flags, config)
-
- let description =
- cmd.contents
- |> option.map(fn(contents) { contents.description })
- |> option.unwrap("")
-
- // create the header block from the name and description
- let header_items =
- [name, description]
- |> list.filter(is_not_empty)
- |> string.join("\n")
-
- // create the subcommands help block
- let subcommands = case subcommands_help(cmd.subcommands) {
- "" -> ""
- subcommands_help_body ->
- config.pretty_help
- |> option.map(fn(p) { heading_style(subcommands_heading, p.subcommands) })
- |> option.unwrap(subcommands_heading) <> "\n\t" <> subcommands_help_body
- }
-
- // join the resulting help blocks into the final help message
- [header_items, usage, flags_help_body, subcommands]
- |> list.filter(is_not_empty)
- |> string.join("\n\n")
-}
-
-// create the help text for subcommands
-fn subcommands_help(cmds: Map(String, CommandNode(a))) -> String {
- cmds
- |> map.map_values(subcommand_help)
- |> map.values
- |> list.sort(string.compare)
- |> string.join("\n\t")
-}
-
-// generate the help text for a subcommand
-fn subcommand_help(name: String, cmd: CommandNode(_)) -> String {
- case cmd.contents {
- None -> name
- Some(contents) -> name <> "\t\t" <> contents.description
- }
-}
-
-/// Style heading text with the provided rgb colouring
-/// this is only intended for use within glint itself.
-///
-fn heading_style(heading: String, colour: Colour) -> String {
- heading
- |> ansi.bold
- |> ansi.underline
- |> ansi.italic
- |> ansi.hex(colour.to_rgb_hex(colour))
- |> ansi.reset
-}
-
-// -- DEPRECATED: STUBS --
-
-/// DEPRECATED: use `glint.cmd` and related new functions instead to create a Command
-///
-/// Create command stubs to be used in `add_command_from_stub`
-///
-pub type Stub(a) {
- Stub(
- path: List(String),
- run: Runner(a),
- flags: List(#(String, Flag)),
- description: String,
- )
-}
-
-/// Add a command to the root given a stub
-///
-@deprecated("use `glint.cmd` and related new functions instead to create a Command")
-pub fn add_command_from_stub(to glint: Glint(a), with stub: Stub(a)) -> Glint(a) {
- add(
- to: glint,
- at: stub.path,
- do: command(stub.run)
- |> flags(stub.flags)
- |> description(stub.description),
- )
-}
diff --git a/aoc2023/build/packages/glint/src/glint/flag.gleam b/aoc2023/build/packages/glint/src/glint/flag.gleam
deleted file mode 100644
index 0a6cae1..0000000
--- a/aoc2023/build/packages/glint/src/glint/flag.gleam
+++ /dev/null
@@ -1,478 +0,0 @@
-import gleam/map
-import gleam/string
-import gleam/result
-import gleam/int
-import gleam/list
-import gleam/float
-import snag.{type Result, type Snag}
-import gleam/option.{type Option, None, Some}
-import glint/flag/constraint.{type Constraint}
-import gleam
-
-/// Flag inputs must start with this prefix
-///
-pub const prefix = "--"
-
-/// The separation character for flag names and their values
-const delimiter = "="
-
-/// Supported flag types.
-///
-pub type Value {
- /// Boolean flags, to be passed in as `--flag=true` or `--flag=false`.
- /// Can be toggled by omitting the desired value like `--flag`.
- /// Toggling will negate the existing value.
- ///
- B(Internal(Bool))
-
- /// Int flags, to be passed in as `--flag=1`
- ///
- I(Internal(Int))
-
- /// List(Int) flags, to be passed in as `--flag=1,2,3`
- ///
- LI(Internal(List(Int)))
-
- /// Float flags, to be passed in as `--flag=1.0`
- ///
- F(Internal(Float))
-
- /// List(Float) flags, to be passed in as `--flag=1.0,2.0`
- ///
- LF(Internal(List(Float)))
-
- /// String flags, to be passed in as `--flag=hello`
- ///
- S(Internal(String))
-
- /// List(String) flags, to be passed in as `--flag=hello,world`
- ///
- LS(Internal(List(String)))
-}
-
-/// A type that facilitates the creation of `Flag`s
-///
-pub opaque type FlagBuilder(a) {
- FlagBuilder(
- desc: Description,
- parser: Parser(a, Snag),
- value: fn(Internal(a)) -> Value,
- default: Option(a),
- )
-}
-
-/// An internal representation of flag contents
-///
-pub opaque type Internal(a) {
- Internal(value: Option(a), parser: Parser(a, Snag))
-}
-
-// Builder initializers
-
-type Parser(a, b) =
- fn(String) -> gleam.Result(a, b)
-
-/// initialise an int flag builder
-///
-pub fn int() -> FlagBuilder(Int) {
- use input <- new(I)
- input
- |> int.parse
- |> result.replace_error(cannot_parse(input, "int"))
-}
-
-/// initialise an int list flag builder
-///
-pub fn int_list() -> FlagBuilder(List(Int)) {
- use input <- new(LI)
- input
- |> string.split(",")
- |> list.try_map(int.parse)
- |> result.replace_error(cannot_parse(input, "int list"))
-}
-
-/// initialise a float flag builder
-///
-pub fn float() -> FlagBuilder(Float) {
- use input <- new(F)
- input
- |> float.parse
- |> result.replace_error(cannot_parse(input, "float"))
-}
-
-/// initialise a float list flag builder
-///
-pub fn float_list() -> FlagBuilder(List(Float)) {
- use input <- new(LF)
- input
- |> string.split(",")
- |> list.try_map(float.parse)
- |> result.replace_error(cannot_parse(input, "float list"))
-}
-
-/// initialise a string flag builder
-///
-pub fn string() -> FlagBuilder(String) {
- new(S, fn(s) { Ok(s) })
-}
-
-/// intitialise a string list flag builder
-///
-pub fn string_list() -> FlagBuilder(List(String)) {
- use input <- new(LS)
- input
- |> string.split(",")
- |> Ok
-}
-
-/// initialise a bool flag builder
-///
-pub fn bool() -> FlagBuilder(Bool) {
- use input <- new(B)
- case string.lowercase(input) {
- "true" | "t" -> Ok(True)
- "false" | "f" -> Ok(False)
- _ -> Error(cannot_parse(input, "bool"))
- }
-}
-
-/// initialize custom builders using a Value constructor and a parsing function
-///
-fn new(valuer: fn(Internal(a)) -> Value, p: Parser(a, Snag)) -> FlagBuilder(a) {
- FlagBuilder(desc: "", parser: p, value: valuer, default: None)
-}
-
-/// convert a FlagBuilder(a) into its corresponding Flag representation
-///
-pub fn build(fb: FlagBuilder(a)) -> Flag {
- Flag(
- value: fb.value(Internal(value: fb.default, parser: fb.parser)),
- description: fb.desc,
- )
-}
-
-/// attach a constraint to a `Flag`
-///
-pub fn constraint(
- builder: FlagBuilder(a),
- constraint: Constraint(a),
-) -> FlagBuilder(a) {
- FlagBuilder(
- ..builder,
- parser: wrap_with_constraint(builder.parser, constraint),
- )
-}
-
-/// attach a Constraint(a) to a Parser(a,Snag)
-/// this function should not be used directly unless
-fn wrap_with_constraint(
- p: Parser(a, Snag),
- constraint: Constraint(a),
-) -> Parser(a, Snag) {
- fn(input: String) -> Result(a) { attempt(p(input), constraint) }
-}
-
-fn attempt(
- val: gleam.Result(a, e),
- f: fn(a) -> gleam.Result(_, e),
-) -> gleam.Result(a, e) {
- use a <- result.try(val)
- result.replace(f(a), a)
-}
-
-/// Flag descriptions
-///
-pub type Description =
- String
-
-/// Flag data and descriptions
-///
-pub type Flag {
- Flag(value: Value, description: Description)
-}
-
-/// attach a description to a `Flag`
-///
-pub fn description(
- for builder: FlagBuilder(a),
- of description: Description,
-) -> FlagBuilder(a) {
- FlagBuilder(..builder, desc: description)
-}
-
-/// Set the default value for a flag `Value`
-///
-pub fn default(for builder: FlagBuilder(a), of default: a) -> FlagBuilder(a) {
- FlagBuilder(..builder, default: Some(default))
-}
-
-/// Associate flag names to their current values.
-///
-pub type Map =
- map.Map(String, Flag)
-
-/// Convert a list of flags to a Map.
-///
-pub fn build_map(flags: List(#(String, Flag))) -> Map {
- map.from_list(flags)
-}
-
-/// Updates a flag value, ensuring that the new value can satisfy the required type.
-/// Assumes that all flag inputs passed in start with --
-/// This function is only intended to be used from glint.execute_root
-///
-pub fn update_flags(in flags: Map, with flag_input: String) -> Result(Map) {
- let flag_input = string.drop_left(flag_input, string.length(prefix))
-
- case string.split_once(flag_input, delimiter) {
- Ok(data) -> update_flag_value(flags, data)
- Error(_) -> attempt_toggle_flag(flags, flag_input)
- }
-}
-
-fn update_flag_value(in flags: Map, with data: #(String, String)) -> Result(Map) {
- let #(key, input) = data
- use contents <- result.try(access(flags, key))
- use value <- result.map(
- compute_flag(with: input, given: contents.value)
- |> result.map_error(layer_invalid_flag(_, key)),
- )
- map.insert(flags, key, Flag(..contents, value: value))
-}
-
-fn attempt_toggle_flag(in flags: Map, at key: String) -> Result(Map) {
- use contents <- result.try(access(flags, key))
- case contents.value {
- B(Internal(None, ..) as internal) ->
- Internal(..internal, value: Some(True))
- |> B
- |> fn(val) { Flag(..contents, value: val) }
- |> map.insert(into: flags, for: key)
- |> Ok()
- B(Internal(Some(val), ..) as internal) ->
- Internal(..internal, value: Some(!val))
- |> B
- |> fn(val) { Flag(..contents, value: val) }
- |> map.insert(into: flags, for: key)
- |> Ok()
- _ -> Error(no_value_flag_err(key))
- }
-}
-
-fn access_type_error(flag_type) {
- snag.error("cannot access flag as " <> flag_type)
-}
-
-fn flag_not_provided_error() {
- snag.error("no value provided")
-}
-
-fn construct_value(
- input: String,
- internal: Internal(a),
- constructor: fn(Internal(a)) -> Value,
-) -> Result(Value) {
- use val <- result.map(internal.parser(input))
- constructor(Internal(..internal, value: Some(val)))
-}
-
-/// Computes the new flag value given the input and the expected flag type
-///
-fn compute_flag(with input: String, given current: Value) -> Result(Value) {
- input
- |> case current {
- I(internal) -> construct_value(_, internal, I)
- LI(internal) -> construct_value(_, internal, LI)
- F(internal) -> construct_value(_, internal, F)
- LF(internal) -> construct_value(_, internal, LF)
- S(internal) -> construct_value(_, internal, S)
- LS(internal) -> construct_value(_, internal, LS)
- B(internal) -> construct_value(_, internal, B)
- }
- |> snag.context("failed to compute value for flag")
-}
-
-// Error creation and manipulation functions
-fn layer_invalid_flag(err: Snag, flag: String) -> Snag {
- snag.layer(err, "invalid flag '" <> flag <> "'")
-}
-
-fn no_value_flag_err(flag_input: String) -> Snag {
- { "flag '" <> flag_input <> "' has no assigned value" }
- |> snag.new()
- |> layer_invalid_flag(flag_input)
-}
-
-fn undefined_flag_err(key: String) -> Snag {
- "flag provided but not defined"
- |> snag.new()
- |> layer_invalid_flag(key)
-}
-
-fn cannot_parse(with value: String, is kind: String) -> Snag {
- { "cannot parse value '" <> value <> "' as " <> kind }
- |> snag.new()
-}
-
-// Help Message Functions
-/// Generate the help message contents for a single flag
-///
-pub fn flag_type_help(flag: #(String, Flag)) {
- let #(name, contents) = flag
- let kind = case contents.value {
- I(_) -> "INT"
- B(_) -> "BOOL"
- F(_) -> "FLOAT"
- LF(_) -> "FLOAT_LIST"
- LI(_) -> "INT_LIST"
- LS(_) -> "STRING_LIST"
- S(_) -> "STRING"
- }
-
- prefix <> name <> delimiter <> "<" <> kind <> ">"
-}
-
-/// Generate help message line for a single flag
-///
-fn flag_help(flag: #(String, Flag)) -> String {
- flag_type_help(flag) <> "\t\t" <> { flag.1 }.description
-}
-
-/// Generate help messages for all flags
-///
-pub fn flags_help(flags: Map) -> List(String) {
- flags
- |> map.to_list
- |> list.map(flag_help)
-}
-
-// -- FLAG ACCESS FUNCTIONS --
-
-/// Access the contents for the associated flag
-///
-fn access(flags: Map, name: String) -> Result(Flag) {
- map.get(flags, name)
- |> result.replace_error(undefined_flag_err(name))
-}
-
-fn get_value(
- from flags: Map,
- at key: String,
- expecting kind: fn(Flag) -> Result(a),
-) -> Result(a) {
- access(flags, key)
- |> result.try(kind)
- |> snag.context("failed to retrieve value for flag '" <> key <> "'")
-}
-
-/// Gets the current value for the provided int flag
-///
-pub fn get_int_value(from flag: Flag) -> Result(Int) {
- case flag.value {
- I(Internal(value: Some(val), ..)) -> Ok(val)
- I(Internal(value: None, ..)) -> flag_not_provided_error()
- _ -> access_type_error("int")
- }
-}
-
-/// Gets the current value for the associated int flag
-///
-pub fn get_int(from flags: Map, for name: String) -> Result(Int) {
- get_value(flags, name, get_int_value)
-}
-
-/// Gets the current value for the provided ints flag
-///
-pub fn get_ints_value(from flag: Flag) -> Result(List(Int)) {
- case flag.value {
- LI(Internal(value: Some(val), ..)) -> Ok(val)
- LI(Internal(value: None, ..)) -> flag_not_provided_error()
- _ -> access_type_error("int list")
- }
-}
-
-/// Gets the current value for the associated ints flag
-///
-pub fn get_ints(from flags: Map, for name: String) -> Result(List(Int)) {
- get_value(flags, name, get_ints_value)
-}
-
-/// Gets the current value for the provided bool flag
-///
-pub fn get_bool_value(from flag: Flag) -> Result(Bool) {
- case flag.value {
- B(Internal(Some(val), ..)) -> Ok(val)
- B(Internal(None, ..)) -> flag_not_provided_error()
- _ -> access_type_error("bool")
- }
-}
-
-/// Gets the current value for the associated bool flag
-///
-pub fn get_bool(from flags: Map, for name: String) -> Result(Bool) {
- get_value(flags, name, get_bool_value)
-}
-
-/// Gets the current value for the provided string flag
-///
-pub fn get_string_value(from flag: Flag) -> Result(String) {
- case flag.value {
- S(Internal(value: Some(val), ..)) -> Ok(val)
- S(Internal(value: None, ..)) -> flag_not_provided_error()
- _ -> access_type_error("string")
- }
-}
-
-/// Gets the current value for the associated string flag
-///
-pub fn get_string(from flags: Map, for name: String) -> Result(String) {
- get_value(flags, name, get_string_value)
-}
-
-/// Gets the current value for the provided strings flag
-///
-pub fn get_strings_value(from flag: Flag) -> Result(List(String)) {
- case flag.value {
- LS(Internal(value: Some(val), ..)) -> Ok(val)
- LS(Internal(value: None, ..)) -> flag_not_provided_error()
- _ -> access_type_error("string list")
- }
-}
-
-/// Gets the current value for the associated strings flag
-///
-pub fn get_strings(from flags: Map, for name: String) -> Result(List(String)) {
- get_value(flags, name, get_strings_value)
-}
-
-/// Gets the current value for the provided float flag
-///
-pub fn get_float_value(from flag: Flag) -> Result(Float) {
- case flag.value {
- F(Internal(value: Some(val), ..)) -> Ok(val)
- F(Internal(value: None, ..)) -> flag_not_provided_error()
- _ -> access_type_error("float")
- }
-}
-
-/// Gets the current value for the associated float flag
-///
-pub fn get_float(from flags: Map, for name: String) -> Result(Float) {
- get_value(flags, name, get_float_value)
-}
-
-/// Gets the current value for the provided floats flag
-///
-pub fn get_floats_value(from flag: Flag) -> Result(List(Float)) {
- case flag.value {
- LF(Internal(value: Some(val), ..)) -> Ok(val)
- LF(Internal(value: None, ..)) -> flag_not_provided_error()
- _ -> access_type_error("float list")
- }
-}
-
-/// Gets the current value for the associated floats flag
-///
-pub fn get_floats(from flags: Map, for name: String) -> Result(List(Float)) {
- get_value(flags, name, get_floats_value)
-}
diff --git a/aoc2023/build/packages/glint/src/glint/flag/constraint.gleam b/aoc2023/build/packages/glint/src/glint/flag/constraint.gleam
deleted file mode 100644
index e474bc2..0000000
--- a/aoc2023/build/packages/glint/src/glint/flag/constraint.gleam
+++ /dev/null
@@ -1,66 +0,0 @@
-import gleam/list
-import gleam/result
-import gleam/string
-import gleam/set
-import snag.{type Result}
-
-/// Constraint type for verifying flag values
-///
-pub type Constraint(a) =
- fn(a) -> Result(Nil)
-
-/// one_of returns a Constraint that ensures the parsed flag value is
-/// one of the allowed values.
-///
-pub fn one_of(allowed: List(a)) -> Constraint(a) {
- let allowed_set = set.from_list(allowed)
- fn(val: a) -> Result(Nil) {
- case set.contains(allowed_set, val) {
- True -> Ok(Nil)
- False ->
- snag.error(
- "invalid value '" <> string.inspect(val) <> "', must be one of: [" <> {
- allowed
- |> list.map(fn(a) { "'" <> string.inspect(a) <> "'" })
- |> string.join(", ") <> "]"
- },
- )
- }
- }
-}
-
-/// none_of returns a Constraint that ensures the parsed flag value is not one of the disallowed values.
-///
-pub fn none_of(disallowed: List(a)) -> Constraint(a) {
- let disallowed_set = set.from_list(disallowed)
- fn(val: a) -> Result(Nil) {
- case set.contains(disallowed_set, val) {
- False -> Ok(Nil)
- True ->
- snag.error(
- "invalid value '" <> string.inspect(val) <> "', must not be one of: [" <> {
- {
- disallowed
- |> list.map(fn(a) { "'" <> string.inspect(a) <> "'" })
- |> string.join(", ") <> "]"
- }
- },
- )
- }
- }
-}
-
-/// each is a convenience function for applying a Constraint(a) to a List(a).
-/// This is useful because the default behaviour for constraints on lists is that they will apply to the list as a whole.
-///
-/// For example, to apply one_of to all items in a `List(Int)`:
-/// ```gleam
-/// [1, 2, 3, 4] |> one_of |> each
-/// ```
-pub fn each(constraint: Constraint(a)) -> Constraint(List(a)) {
- fn(l: List(a)) -> Result(Nil) {
- l
- |> list.try_map(constraint)
- |> result.replace(Nil)
- }
-}
diff --git a/aoc2023/build/packages/glint/src/glint@flag.erl b/aoc2023/build/packages/glint/src/glint@flag.erl
deleted file mode 100644
index bcce6db..0000000
--- a/aoc2023/build/packages/glint/src/glint@flag.erl
+++ /dev/null
@@ -1,523 +0,0 @@
--module(glint@flag).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([string/0, string_list/0, build/1, constraint/2, description/2, default/2, build_map/1, int/0, int_list/0, float/0, float_list/0, bool/0, flag_type_help/1, flags_help/1, update_flags/2, get_int_value/1, get_int/2, get_ints_value/1, get_ints/2, get_bool_value/1, get_bool/2, get_string_value/1, get_string/2, get_strings_value/1, get_strings/2, get_float_value/1, get_float/2, get_floats_value/1, get_floats/2]).
--export_type([value/0, flag_builder/1, internal/1, flag/0]).
-
--type value() :: {b, internal(boolean())} |
- {i, internal(integer())} |
- {li, internal(list(integer()))} |
- {f, internal(float())} |
- {lf, internal(list(float()))} |
- {s, internal(binary())} |
- {ls, internal(list(binary()))}.
-
--opaque flag_builder(FTZ) :: {flag_builder,
- binary(),
- fun((binary()) -> {ok, FTZ} | {error, snag:snag()}),
- fun((internal(FTZ)) -> value()),
- gleam@option:option(FTZ)}.
-
--opaque internal(FUA) :: {internal,
- gleam@option:option(FUA),
- fun((binary()) -> {ok, FUA} | {error, snag:snag()})}.
-
--type flag() :: {flag, value(), binary()}.
-
--spec new(
- fun((internal(FUR)) -> value()),
- fun((binary()) -> {ok, FUR} | {error, snag:snag()})
-) -> flag_builder(FUR).
-new(Valuer, P) ->
- {flag_builder, <<""/utf8>>, P, Valuer, none}.
-
--spec string() -> flag_builder(binary()).
-string() ->
- new(fun(Field@0) -> {s, Field@0} end, fun(S) -> {ok, S} end).
-
--spec string_list() -> flag_builder(list(binary())).
-string_list() ->
- new(fun(Field@0) -> {ls, Field@0} end, fun(Input) -> _pipe = Input,
- _pipe@1 = gleam@string:split(_pipe, <<","/utf8>>),
- {ok, _pipe@1} end).
-
--spec build(flag_builder(any())) -> flag().
-build(Fb) ->
- {flag,
- (erlang:element(4, Fb))(
- {internal, erlang:element(5, Fb), erlang:element(3, Fb)}
- ),
- erlang:element(2, Fb)}.
-
--spec attempt(
- {ok, FVI} | {error, FVJ},
- fun((FVI) -> {ok, any()} | {error, FVJ})
-) -> {ok, FVI} | {error, FVJ}.
-attempt(Val, F) ->
- gleam@result:'try'(Val, fun(A) -> gleam@result:replace(F(A), A) end).
-
--spec wrap_with_constraint(
- fun((binary()) -> {ok, FVC} | {error, snag:snag()}),
- fun((FVC) -> {ok, nil} | {error, snag:snag()})
-) -> fun((binary()) -> {ok, FVC} | {error, snag:snag()}).
-wrap_with_constraint(P, Constraint) ->
- fun(Input) -> attempt(P(Input), Constraint) end.
-
--spec constraint(
- flag_builder(FUY),
- fun((FUY) -> {ok, nil} | {error, snag:snag()})
-) -> flag_builder(FUY).
-constraint(Builder, Constraint) ->
- erlang:setelement(
- 3,
- Builder,
- wrap_with_constraint(erlang:element(3, Builder), Constraint)
- ).
-
--spec description(flag_builder(FVR), binary()) -> flag_builder(FVR).
-description(Builder, Description) ->
- erlang:setelement(2, Builder, Description).
-
--spec default(flag_builder(FVU), FVU) -> flag_builder(FVU).
-default(Builder, Default) ->
- erlang:setelement(5, Builder, {some, Default}).
-
--spec build_map(list({binary(), flag()})) -> gleam@map:map_(binary(), flag()).
-build_map(Flags) ->
- gleam@map:from_list(Flags).
-
--spec access_type_error(binary()) -> {ok, any()} | {error, snag:snag()}.
-access_type_error(Flag_type) ->
- snag:error(<<"cannot access flag as "/utf8, Flag_type/binary>>).
-
--spec flag_not_provided_error() -> {ok, any()} | {error, snag:snag()}.
-flag_not_provided_error() ->
- snag:error(<<"no value provided"/utf8>>).
-
--spec construct_value(binary(), internal(FWE), fun((internal(FWE)) -> value())) -> {ok,
- value()} |
- {error, snag:snag()}.
-construct_value(Input, Internal, Constructor) ->
- gleam@result:map(
- (erlang:element(3, Internal))(Input),
- fun(Val) -> Constructor(erlang:setelement(2, Internal, {some, Val})) end
- ).
-
--spec compute_flag(binary(), value()) -> {ok, value()} | {error, snag:snag()}.
-compute_flag(Input, Current) ->
- _pipe = Input,
- _pipe@1 = case Current of
- {i, Internal} ->
- fun(_capture) ->
- construct_value(
- _capture,
- Internal,
- fun(Field@0) -> {i, Field@0} end
- )
- end;
-
- {li, Internal@1} ->
- fun(_capture@1) ->
- construct_value(
- _capture@1,
- Internal@1,
- fun(Field@0) -> {li, Field@0} end
- )
- end;
-
- {f, Internal@2} ->
- fun(_capture@2) ->
- construct_value(
- _capture@2,
- Internal@2,
- fun(Field@0) -> {f, Field@0} end
- )
- end;
-
- {lf, Internal@3} ->
- fun(_capture@3) ->
- construct_value(
- _capture@3,
- Internal@3,
- fun(Field@0) -> {lf, Field@0} end
- )
- end;
-
- {s, Internal@4} ->
- fun(_capture@4) ->
- construct_value(
- _capture@4,
- Internal@4,
- fun(Field@0) -> {s, Field@0} end
- )
- end;
-
- {ls, Internal@5} ->
- fun(_capture@5) ->
- construct_value(
- _capture@5,
- Internal@5,
- fun(Field@0) -> {ls, Field@0} end
- )
- end;
-
- {b, Internal@6} ->
- fun(_capture@6) ->
- construct_value(
- _capture@6,
- Internal@6,
- fun(Field@0) -> {b, Field@0} end
- )
- end
- end(_pipe),
- snag:context(_pipe@1, <<"failed to compute value for flag"/utf8>>).
-
--spec layer_invalid_flag(snag:snag(), binary()) -> snag:snag().
-layer_invalid_flag(Err, Flag) ->
- snag:layer(Err, <<<<"invalid flag '"/utf8, Flag/binary>>/binary, "'"/utf8>>).
-
--spec no_value_flag_err(binary()) -> snag:snag().
-no_value_flag_err(Flag_input) ->
- _pipe = (<<<<"flag '"/utf8, Flag_input/binary>>/binary,
- "' has no assigned value"/utf8>>),
- _pipe@1 = snag:new(_pipe),
- layer_invalid_flag(_pipe@1, Flag_input).
-
--spec undefined_flag_err(binary()) -> snag:snag().
-undefined_flag_err(Key) ->
- _pipe = <<"flag provided but not defined"/utf8>>,
- _pipe@1 = snag:new(_pipe),
- layer_invalid_flag(_pipe@1, Key).
-
--spec cannot_parse(binary(), binary()) -> snag:snag().
-cannot_parse(Value, Kind) ->
- _pipe = (<<<<<<"cannot parse value '"/utf8, Value/binary>>/binary,
- "' as "/utf8>>/binary,
- Kind/binary>>),
- snag:new(_pipe).
-
--spec int() -> flag_builder(integer()).
-int() ->
- new(fun(Field@0) -> {i, Field@0} end, fun(Input) -> _pipe = Input,
- _pipe@1 = gleam@int:parse(_pipe),
- gleam@result:replace_error(
- _pipe@1,
- cannot_parse(Input, <<"int"/utf8>>)
- ) end).
-
--spec int_list() -> flag_builder(list(integer())).
-int_list() ->
- new(fun(Field@0) -> {li, Field@0} end, fun(Input) -> _pipe = Input,
- _pipe@1 = gleam@string:split(_pipe, <<","/utf8>>),
- _pipe@2 = gleam@list:try_map(_pipe@1, fun gleam@int:parse/1),
- gleam@result:replace_error(
- _pipe@2,
- cannot_parse(Input, <<"int list"/utf8>>)
- ) end).
-
--spec float() -> flag_builder(float()).
-float() ->
- new(fun(Field@0) -> {f, Field@0} end, fun(Input) -> _pipe = Input,
- _pipe@1 = gleam@float:parse(_pipe),
- gleam@result:replace_error(
- _pipe@1,
- cannot_parse(Input, <<"float"/utf8>>)
- ) end).
-
--spec float_list() -> flag_builder(list(float())).
-float_list() ->
- new(fun(Field@0) -> {lf, Field@0} end, fun(Input) -> _pipe = Input,
- _pipe@1 = gleam@string:split(_pipe, <<","/utf8>>),
- _pipe@2 = gleam@list:try_map(_pipe@1, fun gleam@float:parse/1),
- gleam@result:replace_error(
- _pipe@2,
- cannot_parse(Input, <<"float list"/utf8>>)
- ) end).
-
--spec bool() -> flag_builder(boolean()).
-bool() ->
- new(
- fun(Field@0) -> {b, Field@0} end,
- fun(Input) -> case gleam@string:lowercase(Input) of
- <<"true"/utf8>> ->
- {ok, true};
-
- <<"t"/utf8>> ->
- {ok, true};
-
- <<"false"/utf8>> ->
- {ok, false};
-
- <<"f"/utf8>> ->
- {ok, false};
-
- _ ->
- {error, cannot_parse(Input, <<"bool"/utf8>>)}
- end end
- ).
-
--spec flag_type_help({binary(), flag()}) -> binary().
-flag_type_help(Flag) ->
- {Name, Contents} = Flag,
- Kind = case erlang:element(2, Contents) of
- {i, _} ->
- <<"INT"/utf8>>;
-
- {b, _} ->
- <<"BOOL"/utf8>>;
-
- {f, _} ->
- <<"FLOAT"/utf8>>;
-
- {lf, _} ->
- <<"FLOAT_LIST"/utf8>>;
-
- {li, _} ->
- <<"INT_LIST"/utf8>>;
-
- {ls, _} ->
- <<"STRING_LIST"/utf8>>;
-
- {s, _} ->
- <<"STRING"/utf8>>
- end,
- <<<<<<<<<<"--"/utf8, Name/binary>>/binary, "="/utf8>>/binary, "<"/utf8>>/binary,
- Kind/binary>>/binary,
- ">"/utf8>>.
-
--spec flag_help({binary(), flag()}) -> binary().
-flag_help(Flag) ->
- <<<<(flag_type_help(Flag))/binary, "\t\t"/utf8>>/binary,
- (erlang:element(3, (erlang:element(2, Flag))))/binary>>.
-
--spec flags_help(gleam@map:map_(binary(), flag())) -> list(binary()).
-flags_help(Flags) ->
- _pipe = Flags,
- _pipe@1 = gleam@map:to_list(_pipe),
- gleam@list:map(_pipe@1, fun flag_help/1).
-
--spec access(gleam@map:map_(binary(), flag()), binary()) -> {ok, flag()} |
- {error, snag:snag()}.
-access(Flags, Name) ->
- _pipe = gleam@map:get(Flags, Name),
- gleam@result:replace_error(_pipe, undefined_flag_err(Name)).
-
--spec update_flag_value(gleam@map:map_(binary(), flag()), {binary(), binary()}) -> {ok,
- gleam@map:map_(binary(), flag())} |
- {error, snag:snag()}.
-update_flag_value(Flags, Data) ->
- {Key, Input} = Data,
- gleam@result:'try'(
- access(Flags, Key),
- fun(Contents) ->
- gleam@result:map(
- begin
- _pipe = compute_flag(Input, erlang:element(2, Contents)),
- gleam@result:map_error(
- _pipe,
- fun(_capture) -> layer_invalid_flag(_capture, Key) end
- )
- end,
- fun(Value) ->
- gleam@map:insert(
- Flags,
- Key,
- erlang:setelement(2, Contents, Value)
- )
- end
- )
- end
- ).
-
--spec attempt_toggle_flag(gleam@map:map_(binary(), flag()), binary()) -> {ok,
- gleam@map:map_(binary(), flag())} |
- {error, snag:snag()}.
-attempt_toggle_flag(Flags, Key) ->
- gleam@result:'try'(
- access(Flags, Key),
- fun(Contents) -> case erlang:element(2, Contents) of
- {b, {internal, none, _} = Internal} ->
- _pipe = erlang:setelement(2, Internal, {some, true}),
- _pipe@1 = {b, _pipe},
- _pipe@2 = (fun(Val) ->
- erlang:setelement(2, Contents, Val)
- end)(_pipe@1),
- _pipe@3 = gleam@map:insert(Flags, Key, _pipe@2),
- {ok, _pipe@3};
-
- {b, {internal, {some, Val@1}, _} = Internal@1} ->
- _pipe@4 = erlang:setelement(
- 2,
- Internal@1,
- {some, not Val@1}
- ),
- _pipe@5 = {b, _pipe@4},
- _pipe@6 = (fun(Val@2) ->
- erlang:setelement(2, Contents, Val@2)
- end)(_pipe@5),
- _pipe@7 = gleam@map:insert(Flags, Key, _pipe@6),
- {ok, _pipe@7};
-
- _ ->
- {error, no_value_flag_err(Key)}
- end end
- ).
-
--spec update_flags(gleam@map:map_(binary(), flag()), binary()) -> {ok,
- gleam@map:map_(binary(), flag())} |
- {error, snag:snag()}.
-update_flags(Flags, Flag_input) ->
- Flag_input@1 = gleam@string:drop_left(
- Flag_input,
- gleam@string:length(<<"--"/utf8>>)
- ),
- case gleam@string:split_once(Flag_input@1, <<"="/utf8>>) of
- {ok, Data} ->
- update_flag_value(Flags, Data);
-
- {error, _} ->
- attempt_toggle_flag(Flags, Flag_input@1)
- end.
-
--spec get_value(
- gleam@map:map_(binary(), flag()),
- binary(),
- fun((flag()) -> {ok, FWM} | {error, snag:snag()})
-) -> {ok, FWM} | {error, snag:snag()}.
-get_value(Flags, Key, Kind) ->
- _pipe = access(Flags, Key),
- _pipe@1 = gleam@result:'try'(_pipe, Kind),
- snag:context(
- _pipe@1,
- <<<<"failed to retrieve value for flag '"/utf8, Key/binary>>/binary,
- "'"/utf8>>
- ).
-
--spec get_int_value(flag()) -> {ok, integer()} | {error, snag:snag()}.
-get_int_value(Flag) ->
- case erlang:element(2, Flag) of
- {i, {internal, {some, Val}, _}} ->
- {ok, Val};
-
- {i, {internal, none, _}} ->
- flag_not_provided_error();
-
- _ ->
- access_type_error(<<"int"/utf8>>)
- end.
-
--spec get_int(gleam@map:map_(binary(), flag()), binary()) -> {ok, integer()} |
- {error, snag:snag()}.
-get_int(Flags, Name) ->
- get_value(Flags, Name, fun get_int_value/1).
-
--spec get_ints_value(flag()) -> {ok, list(integer())} | {error, snag:snag()}.
-get_ints_value(Flag) ->
- case erlang:element(2, Flag) of
- {li, {internal, {some, Val}, _}} ->
- {ok, Val};
-
- {li, {internal, none, _}} ->
- flag_not_provided_error();
-
- _ ->
- access_type_error(<<"int list"/utf8>>)
- end.
-
--spec get_ints(gleam@map:map_(binary(), flag()), binary()) -> {ok,
- list(integer())} |
- {error, snag:snag()}.
-get_ints(Flags, Name) ->
- get_value(Flags, Name, fun get_ints_value/1).
-
--spec get_bool_value(flag()) -> {ok, boolean()} | {error, snag:snag()}.
-get_bool_value(Flag) ->
- case erlang:element(2, Flag) of
- {b, {internal, {some, Val}, _}} ->
- {ok, Val};
-
- {b, {internal, none, _}} ->
- flag_not_provided_error();
-
- _ ->
- access_type_error(<<"bool"/utf8>>)
- end.
-
--spec get_bool(gleam@map:map_(binary(), flag()), binary()) -> {ok, boolean()} |
- {error, snag:snag()}.
-get_bool(Flags, Name) ->
- get_value(Flags, Name, fun get_bool_value/1).
-
--spec get_string_value(flag()) -> {ok, binary()} | {error, snag:snag()}.
-get_string_value(Flag) ->
- case erlang:element(2, Flag) of
- {s, {internal, {some, Val}, _}} ->
- {ok, Val};
-
- {s, {internal, none, _}} ->
- flag_not_provided_error();
-
- _ ->
- access_type_error(<<"string"/utf8>>)
- end.
-
--spec get_string(gleam@map:map_(binary(), flag()), binary()) -> {ok, binary()} |
- {error, snag:snag()}.
-get_string(Flags, Name) ->
- get_value(Flags, Name, fun get_string_value/1).
-
--spec get_strings_value(flag()) -> {ok, list(binary())} | {error, snag:snag()}.
-get_strings_value(Flag) ->
- case erlang:element(2, Flag) of
- {ls, {internal, {some, Val}, _}} ->
- {ok, Val};
-
- {ls, {internal, none, _}} ->
- flag_not_provided_error();
-
- _ ->
- access_type_error(<<"string list"/utf8>>)
- end.
-
--spec get_strings(gleam@map:map_(binary(), flag()), binary()) -> {ok,
- list(binary())} |
- {error, snag:snag()}.
-get_strings(Flags, Name) ->
- get_value(Flags, Name, fun get_strings_value/1).
-
--spec get_float_value(flag()) -> {ok, float()} | {error, snag:snag()}.
-get_float_value(Flag) ->
- case erlang:element(2, Flag) of
- {f, {internal, {some, Val}, _}} ->
- {ok, Val};
-
- {f, {internal, none, _}} ->
- flag_not_provided_error();
-
- _ ->
- access_type_error(<<"float"/utf8>>)
- end.
-
--spec get_float(gleam@map:map_(binary(), flag()), binary()) -> {ok, float()} |
- {error, snag:snag()}.
-get_float(Flags, Name) ->
- get_value(Flags, Name, fun get_float_value/1).
-
--spec get_floats_value(flag()) -> {ok, list(float())} | {error, snag:snag()}.
-get_floats_value(Flag) ->
- case erlang:element(2, Flag) of
- {lf, {internal, {some, Val}, _}} ->
- {ok, Val};
-
- {lf, {internal, none, _}} ->
- flag_not_provided_error();
-
- _ ->
- access_type_error(<<"float list"/utf8>>)
- end.
-
--spec get_floats(gleam@map:map_(binary(), flag()), binary()) -> {ok,
- list(float())} |
- {error, snag:snag()}.
-get_floats(Flags, Name) ->
- get_value(Flags, Name, fun get_floats_value/1).
diff --git a/aoc2023/build/packages/glint/src/glint@flag@constraint.erl b/aoc2023/build/packages/glint/src/glint@flag@constraint.erl
deleted file mode 100644
index 2978be0..0000000
--- a/aoc2023/build/packages/glint/src/glint@flag@constraint.erl
+++ /dev/null
@@ -1,68 +0,0 @@
--module(glint@flag@constraint).
--compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-
--export([one_of/1, none_of/1, each/1]).
-
--spec one_of(list(FSI)) -> fun((FSI) -> {ok, nil} | {error, snag:snag()}).
-one_of(Allowed) ->
- Allowed_set = gleam@set:from_list(Allowed),
- fun(Val) -> case gleam@set:contains(Allowed_set, Val) of
- true ->
- {ok, nil};
-
- false ->
- snag:error(
- <<<<<<"invalid value '"/utf8,
- (gleam@string:inspect(Val))/binary>>/binary,
- "', must be one of: ["/utf8>>/binary,
- ((<<(begin
- _pipe = Allowed,
- _pipe@1 = gleam@list:map(
- _pipe,
- fun(A) ->
- <<<<"'"/utf8,
- (gleam@string:inspect(A))/binary>>/binary,
- "'"/utf8>>
- end
- ),
- gleam@string:join(_pipe@1, <<", "/utf8>>)
- end)/binary,
- "]"/utf8>>))/binary>>
- )
- end end.
-
--spec none_of(list(FSL)) -> fun((FSL) -> {ok, nil} | {error, snag:snag()}).
-none_of(Disallowed) ->
- Disallowed_set = gleam@set:from_list(Disallowed),
- fun(Val) -> case gleam@set:contains(Disallowed_set, Val) of
- false ->
- {ok, nil};
-
- true ->
- snag:error(
- <<<<<<"invalid value '"/utf8,
- (gleam@string:inspect(Val))/binary>>/binary,
- "', must not be one of: ["/utf8>>/binary,
- (((<<(begin
- _pipe = Disallowed,
- _pipe@1 = gleam@list:map(
- _pipe,
- fun(A) ->
- <<<<"'"/utf8,
- (gleam@string:inspect(A))/binary>>/binary,
- "'"/utf8>>
- end
- ),
- gleam@string:join(_pipe@1, <<", "/utf8>>)
- end)/binary,
- "]"/utf8>>)))/binary>>
- )
- end end.
-
--spec each(fun((FSO) -> {ok, nil} | {error, snag:snag()})) -> fun((list(FSO)) -> {ok,
- nil} |
- {error, snag:snag()}).
-each(Constraint) ->
- fun(L) -> _pipe = L,
- _pipe@1 = gleam@list:try_map(_pipe, Constraint),
- gleam@result:replace(_pipe@1, nil) end.