summaryrefslogtreecommitdiff
path: root/examples/example-picker/src/main.rs
blob: 24357a8c98ac64f3e51c1c44beb7c15db2086e21 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//! `Mingling` Example - Picker
//!
//! ## Step1 - Enable Feature
//! Enable the `parser` feature for mingling in `Cargo.toml`
//! ```toml
//! [dependencies]
//! mingling = { version = "...", features = ["parser"] }
//! ```
//!
//! ## Step2 - Write Code
//! Write the following content into `main.rs`
//!
//! ## Step3 - Build and Run
//! ```bash
//! cargo run --manifest-path ./examples/example-picker/Cargo.toml -- pick Bob
//! cargo run --manifest-path ./examples/example-picker/Cargo.toml -- pick Bob --age -15
//! cargo run --manifest-path ./examples/example-picker/Cargo.toml -- pick --age 99
//! ```

use mingling::{
    AnyOutput,
    macros::{chain, dispatcher, gen_program, pack, r_println, renderer},
    marker::NextProcess,
    parser::Picker,
};

dispatcher!("pick", PickCommand => PickEntry);

#[tokio::main]
async fn main() {
    let mut program = DefaultProgram::new();
    program.with_dispatcher(PickCommand);
    program.exec().await;
}

pack!(NoNameProvided = ());
pack!(ParsedPickInput = (i32, String));

#[chain]
async fn parse(prev: PickEntry) -> NextProcess {
    // Extract arguments from `PickEntry`'s inner and create a `Picker`
    let picker = Picker::new(prev.inner);
    let picked = picker
        // First extract the named argument
        .pick_or("--age", 20)
        .after(|n: i32| n.clamp(0, 100))
        // Then sequentially extract the remaining arguments
        .pick_or_route((), AnyOutput::new(NoNameProvided::default()))
        .unpack();

    match picked {
        Ok(value) => ParsedPickInput::new(value).to_render(),
        Err(e) => e.route_renderer(),
    }
}

#[renderer]
fn render_parsed_pick_input(prev: ParsedPickInput) {
    let (age, name) = prev.inner;
    r_println!("Picked: name = {}, age = {}", name, age);
}

#[renderer]
fn render_no_name_input(_prev: NoNameProvided) {
    r_println!("No name provided.");
}

gen_program!();