-module(clip). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/clip.gleam"). -export([return/1, parameter/1, apply/2, command/1, command1/0, command2/0, command3/0, command4/0, fail/1, opt/2, arg/2, arg_many/2, arg_many1/2, flag/2, help/2, subcommands_with_default/2, subcommands/1, run/2]). -export_type([command/1]). -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(" Functions for building and running `Command`s.\n"). -opaque command(OEZ) :: {command, clip@arg_info:arg_info(), gleam@option:option(clip@help:help()), fun((list(binary())) -> {ok, {OEZ, list(binary())}} | {error, binary()})}. -file("src/clip.gleam", 32). ?DOC( " The `return` function takes a value `val` and produces a `Command` that, when\n" " run, produces `val`. You should only call this function directly when your\n" " command doesn't require any arguments. Otherwise, use `clip.command`.\n" "\n" " ```gleam\n" " clip.return(1) |> clip.run([\"whatever\"])\n" "\n" " // Ok(1)\n" " ```\n" "\n" " See the [subcommand example](https://github.com/drewolson/clip/tree/main/examples/subcommand)\n" " for idiomatic usage of `return`.\n" ). -spec return(OFA) -> command(OFA). return(Val) -> {command, clip@arg_info:empty(), none, fun(Args) -> {ok, {Val, Args}} end}. -file("src/clip.gleam", 57). ?DOC( " The `parameter` function provides an alternative syntax for building curried\n" " functions. The following two code blocks are equivalent:\n" "\n" " ```gleam\n" " fn(a) {\n" " fn(b) {\n" " thing(a, b)\n" " }\n" " }\n" " ```\n" "\n" " ```gleam\n" " {\n" " use a <- clip.parameter\n" " use b <- clip.parameter\n" "\n" " thing(a, b)\n" " }\n" " ```\n" "\n" " You can use either style when calling `clip.command`.\n" ). -spec parameter(fun((OFC) -> OFD)) -> fun((OFC) -> OFD). parameter(F) -> F. -file("src/clip.gleam", 63). ?DOC( " Don't call this function directly. Rather, call `cli.opt`, `clip.flag`,\n" " `clip.arg`, `clip.arg_many`, or `clip.arg_many1`.\n" ). -spec apply(command(fun((OFE) -> OFF)), command(OFE)) -> command(OFF). apply(Mf, Ma) -> {command, clip@arg_info:merge(erlang:element(2, Mf), erlang:element(2, Ma)), gleam@option:'or'(erlang:element(3, Mf), erlang:element(3, Ma)), fun(Args) -> gleam@result:'try'( (erlang:element(4, Mf))(Args), fun(_use0) -> {F, Args1} = _use0, gleam@result:'try'( (erlang:element(4, Ma))(Args1), fun(_use0@1) -> {A, Args2} = _use0@1, {ok, {F(A), Args2}} end ) end ) end}. -file("src/clip.gleam", 91). ?DOC( " The `command` function is use to start building a parser. You provide a\n" " curried function and then provide arguments to be supplied to that function.\n" "\n" " ```gleam\n" " clip.command({\n" " use a <- clip.parameter\n" " use b <- clip.parameter\n" "\n" " #(a, b)\n" " })\n" " |> clip.opt(opt.new(\"first\"))\n" " |> clip.opt(opt.new(\"second\"))\n" " |> clip.run([\"--first\", \"foo\", \"--second\", \"bar\"])\n" "\n" " // Ok(#(\"foo\", \"bar\"))\n" " ```\n" ). -spec command(fun((OFJ) -> OFK)) -> command(fun((OFJ) -> OFK)). command(F) -> return(F). -file("src/clip.gleam", 104). ?DOC( " A pre-built command that takes a single argument and returns its value.\n" "\n" " ```gleam\n" " clip.command1()\n" " |> clip.opt(opt.new(\"first\"))\n" " |> clip.run([\"--first\", \"foo\"])\n" "\n" " // Ok(\"foo\")\n" " ```\n" ). -spec command1() -> command(fun((OFM) -> OFM)). command1() -> return(fun(A) -> A end). -file("src/clip.gleam", 119). ?DOC( " A pre-built command that takes two arguments and returns a tuple of their\n" " values.\n" "\n" " ```gleam\n" " clip.command2()\n" " |> clip.opt(opt.new(\"first\"))\n" " |> clip.opt(opt.new(\"second\"))\n" " |> clip.run([\"--first\", \"foo\", \"--second\", \"bar\"])\n" "\n" " // Ok(#(\"foo\", \"bar\"))\n" " ```\n" ). -spec command2() -> command(fun((OFO) -> fun((OFP) -> {OFO, OFP}))). command2() -> return(fun(A) -> fun(B) -> {A, B} end end). -file("src/clip.gleam", 135). ?DOC( " A pre-built command that takes three arguments and returns a tuple of their\n" " values.\n" "\n" " ```gleam\n" " clip.command3()\n" " |> clip.opt(opt.new(\"first\"))\n" " |> clip.opt(opt.new(\"second\"))\n" " |> clip.opt(opt.new(\"third\"))\n" " |> clip.run([\"--first\", \"foo\", \"--second\", \"bar\", \"--third\", \"baz\"])\n" "\n" " // Ok(#(\"foo\", \"bar\", \"baz\"))\n" " ```\n" ). -spec command3() -> command(fun((OFR) -> fun((OFS) -> fun((OFT) -> {OFR, OFS, OFT})))). command3() -> return(fun(A) -> fun(B) -> fun(C) -> {A, B, C} end end end). -file("src/clip.gleam", 152). ?DOC( " A pre-built command that takes four arguments and returns a tuple of their\n" " values.\n" "\n" " ```gleam\n" " clip.command4()\n" " |> clip.opt(opt.new(\"first\"))\n" " |> clip.opt(opt.new(\"second\"))\n" " |> clip.opt(opt.new(\"third\"))\n" " |> clip.opt(opt.new(\"fourth\"))\n" " |> clip.run([\"--first\", \"foo\", \"--second\", \"bar\", \"--third\", \"baz\", \"--fourth\", \"qux\"])\n" "\n" " // Ok(#(\"foo\", \"bar\", \"baz\", \"qux\"))\n" " ```\n" ). -spec command4() -> command(fun((OFV) -> fun((OFW) -> fun((OFX) -> fun((OFY) -> {OFV, OFW, OFX, OFY}))))). command4() -> return(fun(A) -> fun(B) -> fun(C) -> fun(D) -> {A, B, C, D} end end end end). -file("src/clip.gleam", 157). ?DOC(" Creates a `Command` that always produces `Error(message)` when run.\n"). -spec fail(binary()) -> command(any()). fail(Message) -> {command, clip@arg_info:empty(), none, fun(_) -> {error, Message} end}. -file("src/clip.gleam", 171). ?DOC( " Parse an option built using the `clip/opt` module and provide it to a\n" " `Command` function build using `clip.command()`\n" "\n" " ```gleam\n" " clip.command(fn(a) { a })\n" " |> clip.opt(opt.new(\"first\"))\n" " |> clip.run([\"--first\", \"foo\"])\n" "\n" " // Ok(\"foo\")\n" " ```\n" ). -spec opt(command(fun((OGC) -> OGD)), clip@opt:opt(OGC)) -> command(OGD). opt(Command, Opt) -> apply( Command, {command, clip@opt:to_arg_info(Opt), none, fun(_capture) -> clip@opt:run(Opt, _capture) end} ). -file("src/clip.gleam", 192). ?DOC( " Parse the next positional argument built using the `clip/arg` module and\n" " provide it to a `Command` function build using `clip.command()`\n" "\n" " ```gleam\n" " clip.command(fn(a) { a })\n" " |> clip.arg(arg.new(\"foo\"))\n" " |> clip.run([\"foo\"])\n" "\n" " // Ok(\"foo\")\n" " ```\n" "\n" " `arg` will not attempt to parse options starting with `-` unless the\n" " special `--` value has been previously passed or the option is a negative\n" " integer or float.\n" ). -spec arg(command(fun((OGH) -> OGI)), clip@arg:arg(OGH)) -> command(OGI). arg(Command, Arg) -> apply( Command, {command, clip@arg:to_arg_info(Arg), none, fun(_capture) -> clip@arg:run(Arg, _capture) end} ). -file("src/clip.gleam", 216). ?DOC( " Parse the next zero or more positional arguments built using the `clip/arg`\n" " module and provide them as a `List` to a `Command` function build using\n" " `clip.command()`. `arg_many` is greedy, parsing as many options as possible\n" " until parsing fails. If zero values are parsed successfuly, an empty\n" " `List` is provided.\n" "\n" " ```gleam\n" " clip.command(fn(a) { a })\n" " |> clip.arg_many(arg.new(\"foo\"))\n" " |> clip.run([\"foo\", \"bar\", \"baz\"])\n" "\n" " // Ok([\"foo\", \"bar\", \"baz\"])\n" " ```\n" "\n" " `arg_many` will not attempt to parse options starting with `-` unless the\n" " special `--` value has been previously passed or the option is a negative\n" " integer or float.\n" ). -spec arg_many(command(fun((list(OGM)) -> OGO)), clip@arg:arg(OGM)) -> command(OGO). arg_many(Command, Arg) -> apply( Command, {command, clip@arg:to_arg_info_many(Arg), none, fun(_capture) -> clip@arg:run_many(Arg, _capture) end} ). -file("src/clip.gleam", 239). ?DOC( " Parse the next one or more positional arguments built using the `clip/arg`\n" " module and provide them as a `List` to a `Command` function build using\n" " `clip.command()`. `arg_many` is greedy, parsing as many options as possible\n" " until parsing fails. Parsing fails if zero values are parsed successfully.\n" "\n" " ```gleam\n" " clip.command(fn(a) { a })\n" " |> clip.arg_many1(arg.new(\"foo\"))\n" " |> clip.run([\"foo\", \"bar\", \"baz\"])\n" "\n" " // Ok([\"foo\", \"bar\", \"baz\"])\n" " ```\n" "\n" " `arg_many1` will not attempt to parse options starting with `-` unless the\n" " special `--` value has been previously passed or the option is a negative\n" " integer or float.\n" ). -spec arg_many1(command(fun((list(OGS)) -> OGU)), clip@arg:arg(OGS)) -> command(OGU). arg_many1(Command, Arg) -> apply( Command, {command, clip@arg:to_arg_info_many1(Arg), none, fun(_capture) -> clip@arg:run_many1(Arg, _capture) end} ). -file("src/clip.gleam", 259). ?DOC( " Parse a flag built using the `clip/flag` module and provide it to a\n" " `Command` function build using `clip.command()`\n" "\n" " ```gleam\n" " clip.command(fn(a) { a })\n" " |> clip.flag(flag.new(\"foo\"))\n" " |> clip.run([\"--foo\"])\n" "\n" " // Ok(True)\n" " ```\n" ). -spec flag(command(fun((boolean()) -> OGY)), clip@flag:flag()) -> command(OGY). flag(Command, Flag) -> apply( Command, {command, clip@flag:to_arg_info(Flag), none, fun(_capture) -> clip@flag:run(Flag, _capture) end} ). -file("src/clip.gleam", 307). ?DOC( " Add the help (`-h`, `--help`) flags to your program to display usage help\n" " to the user. See the `clip/help` module for producing simple and custom help\n" " text.\n" ). -spec help(command(OHS), clip@help:help()) -> command(OHS). help(Command, Help) -> {command, erlang:element(2, Command), {some, Help}, erlang:element(4, Command)}. -file("src/clip.gleam", 311). -spec wrap_help(command(OHV), clip@help:help()) -> fun((list(binary())) -> {ok, {OHV, list(binary())}} | {error, binary()}). wrap_help(Command, Help) -> Help_info = begin _record = clip@arg_info:empty(), {arg_info, erlang:element(2, _record), erlang:element(3, _record), [{flag_info, <<"help"/utf8>>, {some, <<"h"/utf8>>}, {some, <<"Print this help"/utf8>>}}], erlang:element(5, _record)} end, fun(Args) -> case Args of [<<"-h"/utf8>> | _] -> {error, clip@help:run( Help, clip@arg_info:merge( erlang:element(2, Command), Help_info ) )}; [<<"--help"/utf8>> | _] -> {error, clip@help:run( Help, clip@arg_info:merge( erlang:element(2, Command), Help_info ) )}; Other -> (erlang:element(4, Command))(Other) end end. -file("src/clip.gleam", 329). -spec run_aux(command(OIB), list(binary())) -> {ok, {OIB, list(binary())}} | {error, binary()}. run_aux(Command, Args) -> F = case erlang:element(3, Command) of none -> erlang:element(4, Command); {some, Help} -> wrap_help(Command, Help) end, F(Args). -file("src/clip.gleam", 266). -spec run_subcommands( list({binary(), command(OHB)}), command(OHB), list(binary()) ) -> {ok, {OHB, list(binary())}} | {error, binary()}. run_subcommands(Subcommands, Default, Args) -> case {Subcommands, Args} of {[{Name, Command} | _], [Head | Rest]} when Name =:= Head -> run_aux(Command, Rest); {[_ | Rest@1], _} -> run_subcommands(Rest@1, Default, Args); {[], _} -> run_aux(Default, Args) end. -file("src/clip.gleam", 282). ?DOC( " Build a command with subcommands and a default top-level command if no\n" " subcommand matches. This is an advanced use case, see the examples directory\n" " for more help.\n" ). -spec subcommands_with_default(list({binary(), command(OHJ)}), command(OHJ)) -> command(OHJ). subcommands_with_default(Subcommands, Default) -> Sub_names = gleam@list:map(Subcommands, fun(P) -> erlang:element(1, P) end), Sub_arg_info = begin _record = erlang:element(2, Default), {arg_info, erlang:element(2, _record), erlang:element(3, _record), erlang:element(4, _record), Sub_names} end, apply( return(fun(A) -> A end), {command, Sub_arg_info, none, fun(_capture) -> run_subcommands(Subcommands, Default, _capture) end} ). -file("src/clip.gleam", 300). ?DOC( " Build a command with subcommands. This is an advanced use case, see the\n" " examples directory for more help.\n" ). -spec subcommands(list({binary(), command(OHO)})) -> command(OHO). subcommands(Subcommands) -> subcommands_with_default( Subcommands, fail(<<"No subcommand provided"/utf8>>) ). -file("src/clip.gleam", 343). ?DOC( " Run a command. Running a `Command(a)` will return either `Ok(a)` or an\n" " `Error(String)`. The `Error` value is intended to be printed to the user.\n" ). -spec run(command(OIH), list(binary())) -> {ok, OIH} | {error, binary()}. run(Command, Args) -> case run_aux(Command, Args) of {ok, {A, _}} -> {ok, A}; {error, E} -> {error, E} end.