Hi! This is my first time using this library, and I find it pretty cool and useful. The docs are great, too — although I wish the library was a little bit more self-explanatory, but you can't have it all.
Anyway, I've spent quite some time reading docs to no avail, searching for issues and discussions, experimenting with code, and was in the middle of writing a discussion post of my own when I finally realized how to make a command parser without any options of its own using the combinatoric API.
The first solution was to have a pure value as the only option, like so:
enum Command {
Run { _placeholder: () },
// ...
}
fn run() -> impl bpaf::Parser<Command> {
let _placeholder = bpaf::pure(());
bpaf::construct!(Command::Run { _placeholder })
.to_options()
.descr("Run something")
.command("run")
}
This made it work, but I still had to destructure a useless value when using it:
match inv.command {
cmd::Command::Run { _placeholder } => {}
// ...
}
However the real solution was much closer to what I tried naturally, just needed somewhat unexpected changes:
#[derive(Clone)]
enum Command {
Run,
// ...
}
fn run() -> impl bpaf::Parser<Command> {
bpaf::construct!(Command::Run {})
.to_options()
.descr("Run something")
.command("run")
}
The first unexpected thing is that the construct! macro didn't work with just Command::Run — failing with "unexpected token in input" from rust-analyzer, and this build error:
error: no rules expected `::`
--> src/cmd.rs:50:26
|
50 | bpaf::construct!(Command::Run)
| ^^ no rules expected this token in macro call
|
note: while trying to match `(`
--> /home/mks/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bpaf-0.9.19/src/lib.rs:418:52
|
418 | (@prepare $ty:tt [$($fields:tt)*] $field:ident () $(, $($rest:tt)*)? ) => {{
| ^
So I had to add empty curly braces {} which gave me a different error that suggested adding #[derive(Clone)] to the Command enum.
Regular error on `.to_options()` suggesting I derive Clone on my enum
error[E0599]: the method `to_options` exists for struct `ParsePure<Command>`, but its trait bounds were not satisfied
--> src/cmd.rs:48:4
|
8 | pub enum Command {
| ---------------- doesn't satisfy `cmd::Command: Clone`
...
47 | / bpaf::construct!(Command::Run {})
48 | | .to_options()
| | -^^^^^^^^^^ method cannot be called on `ParsePure<Command>` due to unsatisfied trait bounds
| |_________|
|
|
::: /home/mks/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bpaf-0.9.19/src/structs.rs:852:1
|
852 | pub struct ParsePure<T>(pub(crate) T);
| ----------------------- doesn't satisfy `_: Parser<Command>`
|
= note: the following trait bounds were not satisfied:
`cmd::Command: Clone`
which is required by `bpaf::structs::ParsePure<cmd::Command>: Parser<cmd::Command>`
help: consider annotating `cmd::Command` with `#[derive(Clone)]`
|
8 + #[derive(Clone)]
9 | pub enum Command {
|
And adding the derive made it finally work!
So, I think it would be really cool to add documentation on how to properly do this to the appropriate tutorial page, and the command method.
Bonus points if the library could be made to support the proper syntax to construct empty enum variants (remove the need for curly braces).
P.S. Now I know that all struct members must implement Clone, I just didn't notice it before since most things implement it, and I didn't need to use pure values of enums.
P.P.S. I did find a discussion which showed how to achieve the same setup with the derive API, and it seems much more self-explanatory (whether it is documented or not — I haven't checked).
Hi! This is my first time using this library, and I find it pretty cool and useful. The docs are great, too — although I wish the library was a little bit more self-explanatory, but you can't have it all.
Anyway, I've spent quite some time reading docs to no avail, searching for issues and discussions, experimenting with code, and was in the middle of writing a discussion post of my own when I finally realized how to make a command parser without any options of its own using the combinatoric API.
The first solution was to have a pure value as the only option, like so:
This made it work, but I still had to destructure a useless value when using it:
However the real solution was much closer to what I tried naturally, just needed somewhat unexpected changes:
The first unexpected thing is that the
construct!macro didn't work with justCommand::Run— failing with "unexpected token in input" from rust-analyzer, and this build error:So I had to add empty curly braces
{}which gave me a different error that suggested adding#[derive(Clone)]to theCommandenum.Regular error on `.to_options()` suggesting I derive Clone on my enum
And adding the derive made it finally work!
So, I think it would be really cool to add documentation on how to properly do this to the appropriate tutorial page, and the command method.
Bonus points if the library could be made to support the proper syntax to construct empty enum variants (remove the need for curly braces).
P.S. Now I know that all struct members must implement
Clone, I just didn't notice it before since most things implement it, and I didn't need to use pure values of enums.P.P.S. I did find a discussion which showed how to achieve the same setup with the derive API, and it seems much more self-explanatory (whether it is documented or not — I haven't checked).