Created
January 8, 2025 08:56
-
-
Save smores56/dc7b37f73114df11d28cd6a148987dea to your computer and use it in GitHub Desktop.
Weaver experimental API using terse builders
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module [ArgTypeSelector.*, custom, str, u64] | |
# Making builders pass through this type sets up the type to parse each Arg into. | |
ArgTypeSelector := [ArgTypeSelector ()] | |
custom : ArgTypeSelector, Str, ValueParser a -> ArgValueParser a | |
custom = |ArgTypeSelector.(), type_name, parser| | |
ArgValueParser.({ type_name, parser }) | |
str : ArgTypeSelector -> ArgValueParser Str | |
str = |ArgTypeSelector.()| | |
ArgValueParser.({ type_name: "str", parser: Arg.as_str }) | |
u64 : ArgTypeSelector -> ArgValueParser U64 | |
u64 = |ArgTypeSelector.()| | |
ArgValueParser.({ type_name: "u64", parser: .as_str().try(.to_u64()) }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module [ArgValueParser.*, short, long] | |
# Making builders pass through this type ensures that options provide at least `short` or `long`. | |
ArgValueParser a := [ArgValueParser { type_name: Str, parser: (ValueParser a) }] | |
short : ArgValueParser a, Str -> OptionConfigParams a | |
short = |ArgValueParser.({ type_name, parser }), short| | |
OptionConfigParams.({ | |
short, | |
long: "", | |
help: "", | |
type: type_name, | |
parser, | |
default: NoDefault, | |
}) | |
long : ArgValueParser a, Str -> OptionConfigParams a | |
long = |ArgValueParser.({ type_name, parser }), short| | |
OptionConfigParams.({ | |
short: "", | |
long, | |
help: "", | |
type: type_name, | |
parser, | |
default: NoDefault, | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module [InvalidValue, DefaultValue, ValueParser] | |
InvalidValue : [InvalidNumStr, InvalidValue Str, InvalidUtf8] | |
DefaultValue a : [NoDefault, Value a, Generate (() -> a)] | |
## A parser that extracts an argument value from a string. | |
ValueParser a : Arg -> Result a InvalidValue |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module [single, maybe] | |
builder_with_option_parser : OptionConfig, (List ArgValue -> Result data ArgExtractErr) -> CliBuilder data from_action to_action | |
builder_with_option_parser = \option, value_parser -> | |
arg_parser = |args| | |
{ values, remaining_args } = extract_option_values({ args, option })? | |
data = value_parser(values)? | |
Ok({ data, remaining_args }) | |
Builder.from_arg_parser(arg_parser).add_option(option) | |
get_default_for_option = |option, default| | |
when default is | |
Value(default_value) -> Ok(default_value) | |
Generate(default_value_fn) -> Ok(default_value_fn()) | |
NoDefault -> Err(MissingOption(option)) | |
single : (ArgTypeSelector -> OptionConfigParams a) -> CliBuilder a GetOptionsAction GetOptionsAction | |
single = |params_builder| | |
OptionConfigParams.(params) = params_builder(ArgTypeSelector.()) | |
option = { | |
expected_value: ExpectsValue(params.type), | |
plurality: One, | |
short: params.short, | |
long: params.long, | |
help: params.help, | |
} | |
value_parser = |values| | |
value = get_maybe_value(values, option)? | |
when value is | |
Ok(Ok(val)) -> | |
parser(val).map_err(|err| InvalidOptionValue(err, option)) | |
Ok(Err(NoValue)) -> Err(NoValueProvidedForOption(option)) | |
Err(NoValue) -> get_default_for_option(option, default) | |
builder_with_option_parser(option, value_parser) | |
# Default values can't be used with `maybe`, we could prevent them from being passed with | |
# a phantom type variable on `OptionConfigParams`. | |
maybe : (ArgTypeSelector -> OptionConfigParams a) -> CliBuilder (Result data [NoValue]) GetOptionsAction GetOptionsAction | |
maybe = |params_builder| | |
OptionConfigParams.(params) = params_builder(ArgTypeSelector.()) | |
option = { | |
expected_value: ExpectsValue(params.type), | |
plurality: Optional, | |
short: params.short, | |
long: params.long, | |
help: params.help, | |
} | |
value_parser = |values| | |
value = get_maybe_value(values, option)? | |
when value is | |
Ok(Ok(val)) -> | |
parser(val).map(Ok).map_err(|err| InvalidOptionValue(err, option)) | |
Ok(Err(NoValue)) -> Err(NoValueProvidedForOption(option)) | |
Err(NoValue) -> Ok(Err(NoValue)) | |
builder_with_option_parser(option, value_parser) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module [ | |
OptionConfigParams.*, | |
short, | |
long, | |
help, | |
no_default, | |
default, | |
default_fn, | |
] | |
OptionConfigParams a := [OptionConfigParams { | |
short : Str, | |
long : Str, | |
help : Str, | |
type : Str, | |
parser : ValueParser a, | |
default : DefaultValue a, | |
}] | |
short : OptionConfigParams a, Str -> OptionConfigParams a | |
short = |OptionConfigParams.(params), short| | |
OptionConfigParams.({ short, ..params }) | |
long : OptionConfigParams a, Str -> OptionConfigParams a | |
long = |OptionConfigParams.(params), long| | |
OptionConfigParams.({ long, ..params }) | |
help : OptionConfigParams a, Str -> OptionConfigParams a | |
help = |OptionConfigParams.(params), help| | |
OptionConfigParams.({ help, ..params }) | |
no_default : OptionConfigParams a -> OptionConfigParams a | |
no_default = |OptionConfigParams.(params)| | |
OptionConfigParams.({ default: NoDefault, ..params }) | |
default : OptionConfigParams a, a -> OptionConfigParams a | |
default = |OptionConfigParams.(params), default| | |
OptionConfigParams.({ default: Value(default), ..params }) | |
default_fn : OptionConfigParams a, (() -> a) -> OptionConfigParams a | |
default_fn = |OptionConfigParams.(params), default_fn| | |
OptionConfigParams.({ default: Calculate(default_fn), ..params }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app [main!] { cli: platform "<basic-cli>" } | |
import weaver.Opt | |
import weaver.Cli | |
import cli.Stdout | |
main! = |args| | |
data = | |
cli_parser.parse_or_display_message(args) | |
.on_err!(|message| | |
Stdout.line!(message)? | |
Err(Exit(1, ""))) | |
)? | |
Stdout.line!( | |
""" | |
Successfully parsed! Here's what I got: | |
${data.to_str()} | |
""" | |
)? | |
Ok({}) | |
cli_parser = | |
{ Cli.weave <- | |
force: Opt.flag(.short("f").help("Force the task to complete.")), | |
alpha: Opt.single( | |
.u64() | |
.short("a") | |
.help("Set the alpha level.") | |
.default_fn(|| 1.left_shift_by(7)), | |
), | |
files: Param.list(.str().name("files").help("The rest of the files.")), | |
} | |
.finish({ | |
name: "basic", | |
version: "v0.0.1", | |
authors: ["Some One <[email protected]>"], | |
description: "This is a basic example of what you can build with Weaver", | |
}) | |
.assert_valid() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment