aboutsummaryrefslogtreecommitdiff
path: root/examples/example-lazy-resources/src/main.rs
blob: 3533ae20c9b5b5912a73ce0215790fffdc810e71 (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
81
82
83
84
85
86
87
88
89
90
91
92
//! Example Lazy Resources
//!
//! > This example demonstrates how to use `LazyRes` for lazy resource initialization.
//!
//! Run:
//! ```bash
//! cargo run --manifest-path examples/example-lazy-resources/Cargo.toml --quiet none
//!
//! cargo run --manifest-path examples/example-lazy-resources/Cargo.toml --quiet show
//! ```
//!
//! Output:
//! ```plaintext
//! None
//!
//! Initialized
//! foo: bar
//! rust: lang
//! baz: qux
//! hello: world
//! key: value
//! ```

use std::collections::BTreeMap;

use mingling::{LazyInit, LazyRes, prelude::*};

type Key = String;
type Value = String;

// Define a resource that requires time-consuming initialization
#[derive(Default, Clone)]
pub struct ResLargeData {
    pub data: BTreeMap<Key, Value>,
}

fn init_res_large_data() -> ResLargeData {
    // Perform time-consuming initialization here
    let mut data = BTreeMap::new();
    data.insert("foo".to_string(), "bar".to_string());
    data.insert("baz".to_string(), "qux".to_string());
    data.insert("hello".to_string(), "world".to_string());
    data.insert("rust".to_string(), "lang".to_string());
    data.insert("key".to_string(), "value".to_string());

    // Print to indicate initialization is complete
    println!("Initialized");
    ResLargeData { data }
}

dispatcher!("show", CMDShow => EntryShow);
dispatcher!("none", CMDNone => EntryNone);

pack!(ResultShow = BTreeMap<Key, Value>);

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

    // --------- IMPORTANT ---------
    //                     _ Use lazy_init to create LazyRes<ResLargeData>
    //                    /
    //                    vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    program.with_resource(ResLargeData::lazy_init(init_res_large_data));
    // --------- IMPORTANT ---------

    program.with_dispatchers((CMDShow, CMDNone));
    program.exec_and_exit();
}

// Inject LazyRes instead of a normal resource
//                                           __________________________ Must use &mut because `get_ref` and `get_mut`
//                                          /                             both require mutable borrow
//                                          |     _____________________ Use LazyRes<ResLargeData>
//                                          |    /                        instead of ResLargeData
#[renderer] //                              vvvv vvvvvvvvvvvvvvvvvvvvv
fn render_entry_show(_args: EntryShow, res: &mut LazyRes<ResLargeData>) {
    //             _______ Initialization happens here
    //            /
    //            vvvvvvv
    let res = res.get_ref();
    for (key, value) in &res.data {
        r_println!("{}: {}", key, value);
    }
}

// When not using LazyRes<ResLargeData>, it will not be initialized
#[renderer]
fn render_entry_none(_args: EntryNone) {
    r_println!("None");
}

gen_program!();