aboutsummaryrefslogtreecommitdiff
path: root/examples/example-setup/src/main.rs
blob: 523a567db8068511ff978e4b54d472cb8dd4fddf (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
80
//! Example Setup
//!
//! > This example demonstrates how to build a custom Setup that encapsulates a
//! > group of related resources and registers them with `with_resource`.

use mingling::{Program, macros::program_setup, prelude::*};
use std::io::Write;

// A group of related resources — here, the demo app's identity.
// Resource types are plain structs: any `Default + Clone + Send + Sync` type
// can be used as a resource, and it is identified by its type.
#[derive(Default, Clone)]
struct ResAppName {
    name: String,
}

#[derive(Default, Clone)]
struct ResAppVersion {
    version: String,
}

#[derive(Default, Clone)]
struct ResGreetingPrefix {
    prefix: String,
}

fn main() {
    let mut program = ThisProgram::new();

    // --------- IMPORTANT ---------
    // Introduce `CustomSetup` generated by `custom_setup`
    program.with_setup(CustomSetup);
    // --------- IMPORTANT ---------

    program.exec_and_exit();
}

// --------- IMPORTANT ---------
// Define `CustomSetup` (inferred from `custom_setup`)
// Package part of the program construction logic into this type for modular
// management — e.g. register a group of related resources here.
#[program_setup]
fn custom_setup(program: &mut Program<ThisProgram>) {
    program.with_resource(ResAppName {
        name: "mingling".to_string(),
    });
    program.with_resource(ResAppVersion {
        version: "0.5.0".to_string(),
    });
    program.with_resource(ResGreetingPrefix {
        prefix: "Hello".to_string(),
    });
}
// --------- IMPORTANT ---------

dispatcher!("greet", EntryGreet);

pack!(ResultGreeting = String);

/// Chain: reads the `ResAppName` and `ResAppVersion` resources.
#[chain]
fn handle_greet(args: EntryGreet, app: &ResAppName, version: &ResAppVersion) -> Next {
    let who = args
        .inner
        .first()
        .cloned()
        .unwrap_or_else(|| "World".to_string());
    let greeting: ResultGreeting = format!("{} from {} v{}", who, app.name, version.version).into();
    greeting.into()
}

/// Renderer: injects the `ResGreetingPrefix` resource to decorate the output.
#[renderer]
fn render_greet(greeting: ResultGreeting, prefix: &ResGreetingPrefix) -> RenderResult {
    let mut render_result = RenderResult::new();
    writeln!(render_result, "{}, {}!", prefix.prefix, *greeting).ok();
    render_result
}

gen_program!();