Skip to content

Commit

Permalink
Merge pull request #265 from pacak/rc-0.9.4
Browse files Browse the repository at this point in the history
Example for dynamic parser
  • Loading branch information
pacak authored Aug 8, 2023
2 parents d6c37ac + 584f085 commit 1ace1d8
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bpaf"
version = "0.9.3"
version = "0.9.4"
edition = "2021"
categories = ["command-line-interface"]
description = "A simple Command Line Argument Parser with parser combinators"
Expand Down
6 changes: 3 additions & 3 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Change Log

## bpaf [0.9.4] - Unreleased
- add `help` to `ParseFlag` and `ParseArgument `
## bpaf [0.9.4] - 2023-08-08
- add `help` to `ParseFlag` and `ParseArgument`
- stop deprecating `Parser::run`
- documentation
- Lots of docs.rs documentation improvements
- changes to rendered markdown

## bpaf [0.9.3], bpaf_derive [0.5.3] - 2023-07-26
Expand Down
2 changes: 1 addition & 1 deletion bpaf_cauwugo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ description = "A cargo frontend with dynamic completion"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bpaf = { version = "0.9.3", path = "../", features = ["derive", "autocomplete"] }
bpaf = { version = "0.9.4", path = "../", features = ["derive", "autocomplete"] }
cargo_metadata = "0.17.0"
once_cell = "1.13.1"

Expand Down
73 changes: 73 additions & 0 deletions examples/dynamic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//! You can construct parser at runtime without having a concrete type too

use bpaf::*;

#[derive(Debug, Clone)]
enum Value {
Bool(bool),
Number(usize),
String(String),
}

fn number(name: &'static str) -> impl Parser<(String, Value)> {
let label = name.to_string();
long(name)
.argument::<usize>("NUM")
.map(move |n| (label.clone(), Value::Number(n)))
}

fn bool(name: &'static str) -> impl Parser<(String, Value)> {
let label = name.to_string();
long(name)
.switch()
.map(move |n| (label.clone(), Value::Bool(n)))
}

fn string(name: &'static str) -> impl Parser<(String, Value)> {
let label = name.to_string();
long(name)
.help("this can use a help message")
.argument::<String>("NUM")
.map(move |n| (label.clone(), Value::String(n)))
}

fn cons<T>(acc: Box<dyn Parser<Vec<T>>>, cur: Box<dyn Parser<T>>) -> Box<dyn Parser<Vec<T>>>
where
T: 'static,
{
construct!(acc, cur)
.map(|(mut acc, cur)| {
acc.push(cur);
acc
})
.boxed()
}

enum Ty {
Bool,
Number,
String,
}

fn main() {
let items = &[
("banana", Ty::Bool),
("width", Ty::Number),
("name", Ty::String),
];

let mut parser = pure(Vec::<(String, Value)>::new()).boxed();
for (name, ty) in items {
parser = cons(
parser,
match ty {
Ty::Bool => bool(name).boxed(),
Ty::Number => number(name).boxed(),
Ty::String => string(name).boxed(),
},
)
}

let options = parser.run();
println!("{:?}", options);
}

0 comments on commit 1ace1d8

Please sign in to comment.