summaryrefslogtreecommitdiff
path: root/examples/example-general-renderer/src/main.rs
blob: 8790a06c0ea99a83523069648c7863be20d7652e (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
69
70
71
72
73
74
75
76
77
78
79
//! `Mingling` Example - General Renderer
//!
//! ## Step1 - Enable Feature
//! Enable the `general_renderer` feature for mingling in `Cargo.toml`
//! ```toml
//! [dependencies]
//! mingling = { version = "...", features = ["general_renderer", "parser"] }
//! ```
//!
//! ## Step2 - Add Dependencies
//! Add `serde` dependency to `Cargo.toml` for serialization support
//! ```toml
//! [dependencies]
//! serde = { version = "1", features = ["derive"] }
//! ```
//!
//! ## Step3 - Write Code
//! Write the following content into `main.rs`
//!
//! ## Step3 - Build and Run
//! ```bash
//! cargo run --manifest-path ./examples/example-general-renderer/Cargo.toml -- render Bob 22
//! cargo run --manifest-path ./examples/example-general-renderer/Cargo.toml -- render Bob 22 --json
//! cargo run --manifest-path ./examples/example-general-renderer/Cargo.toml -- render Bob 22 --yaml
//! ```
//!
//! Will print:
//! ```plain
//! Bob is 22 years old
//! {"member_name":"Bob","member_age":22}
//! member_name: Bob
//! member_age: 22
//! ```

use mingling::{
    AnyOutput, Groupped,
    macros::{chain, dispatcher, gen_program, r_println, renderer},
    marker::NextProcess,
    parser::Picker,
    setup::GeneralRendererSetup,
};
use serde::Serialize;

dispatcher!("render", RenderCommand => RenderCommandEntry);

#[tokio::main]
async fn main() {
    let mut program = DefaultProgram::new();
    // Add `GeneralRendererSetup` to receive user input `--json` `--yaml` parameters
    program.with_setup(GeneralRendererSetup);
    program.with_dispatcher(RenderCommand);
    program.exec().await;
}

// Manually implement Info struct
#[derive(Serialize, Groupped)]
struct Info {
    #[serde(rename = "member_name")]
    name: String,
    #[serde(rename = "member_age")]
    age: i32,
}

#[chain]
async fn parse_render(prev: RenderCommandEntry) -> NextProcess {
    let (name, age) = Picker::<AnyOutput<DefaultProgram>>::new(prev.inner)
        .pick::<String>(())
        .pick::<i32>(())
        .unpack_directly();
    AnyOutput::new(Info { name, age }).route_renderer()
}

// Implement default renderer for when general_renderer is not specified
#[renderer]
fn render_info(prev: Info) {
    r_println!("{} is {} years old", prev.name, prev.age);
}

gen_program!();