inertia_rust/
macros.rs

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
93
94
95
96
97
#[macro_export]
macro_rules! hashmap {
    () => ( std::collections::HashMap::new() );
    ($( $key: expr => $value: expr ),+ $(,)?) => {
        {
            let mut map = std::collections::HashMap::new();
            $(
                map.insert($key, $value);
            )*
            map
        }
    };
}

#[macro_export]
macro_rules! prop_resolver {
    () => (std::sync::Arc::new(move || Box::pin(async move { () })));

    ($($clone_stmt: stmt),+; $block: block) => {{
        std::sync::Arc::new(move || {
            $($clone_stmt)+
            Box::pin(async move $block)
        })
    }};

    ($block: block) => {{
        std::sync::Arc::new(move || Box::pin(async move $block))
    }};
}

#[cfg(test)]
mod test {
    use std::{
        collections::HashMap,
        sync::{Arc, Mutex},
    };

    use crate::InertiaProp;

    #[test]
    fn test_hashmap_macro() {
        let mut manual_hashmap = HashMap::new();
        manual_hashmap.insert("foo".to_string(), 10);
        manual_hashmap.insert("bar".to_string(), 25);
        manual_hashmap.insert("baz".to_string(), 49020);

        let macro_hashmap = hashmap![
            "foo".to_string() => 10,
            "bar".to_string() => 25,
            "baz".to_string() => 49020,
        ];

        assert_eq!(manual_hashmap, macro_hashmap);
        assert_eq!(
            HashMap::<_, _>::new() as HashMap<String, String>,
            hashmap![]
        );
    }

    async fn an_async_operation() {}

    #[tokio::test]
    async fn test_prop_resolver_with_moving_let() {
        let message = Arc::new("Super important and often used message!");
        let counter = Arc::new(Mutex::new(1));

        let counter_clone = counter.clone();
        let message_clone = message.clone();

        let prop_with_macro = InertiaProp::lazy(prop_resolver!(
            let counter_clone = counter_clone.clone(),
            let message_clone = message_clone.clone();
            {
                an_async_operation().await;
                format!("{} {}", message_clone, *counter_clone.lock().unwrap()).into()
            }
        ));

        let counter_clone = counter.clone();
        let message_clone = message.clone();

        let prop_with_arc = InertiaProp::lazy(Arc::new(move || {
            let counter_clone = counter_clone.clone();
            let message_clone = message_clone.clone();

            Box::pin(async move {
                an_async_operation().await;
                format!("{} {}", message_clone, *counter_clone.lock().unwrap()).into()
            })
        }));

        assert_eq!(
            prop_with_arc.resolve_unconditionally().await,
            prop_with_macro.resolve_unconditionally().await
        );
    }
}