leon/
macros.rs

1#[doc(hidden)]
2#[macro_export]
3macro_rules! __template_item {
4    () => {};
5    ({ $key:literal }) => {
6        $crate::Item::Key($key)
7    };
8    ( $text:literal ) => {
9        $crate::Item::Text($text)
10    };
11}
12
13#[doc(hidden)]
14#[macro_export]
15macro_rules! __template_impl {
16    ($( $token:tt ),* ; $default:expr) => {
17        $crate::Template::new(
18            {
19                const ITEMS: &'static [$crate::Item<'static>] = &[
20                    $(
21                        $crate::__template_item!($token)
22                    ),*
23                ];
24                ITEMS
25            },
26            $default,
27        )
28    };
29}
30
31/// Construct a template constant using syntax similar to the template to be
32/// passed to [`Template::parse`](crate::Template::parse).
33///
34/// This is essentially a shorthand for:
35///
36/// ```
37/// use leon::{Item, Template};
38/// Template::new({
39///     const ITEMS: &'static [Item<'static>] = &[Item::Text("Hello "), Item::Key("name")];
40///     ITEMS
41/// }, Some("world"));
42/// ```
43///
44/// # Examples
45///
46/// ```
47/// assert_eq!(
48///     leon::template!("Hello ", {"name"})
49///         .render(&[("name", "Магда Нахман")])
50///         .unwrap(),
51///     "Hello Магда Нахман",
52/// );
53/// ```
54///
55/// With a default:
56///
57/// ```
58/// assert_eq!(
59///     leon::template!("Hello ", {"name"}; "M. P. T. Acharya")
60///         .render(&[("city", "Madras")])
61///         .unwrap(),
62///     "Hello M. P. T. Acharya",
63/// );
64/// ```
65#[macro_export]
66macro_rules! template {
67    () => {
68        $crate::Template::new(
69            {
70                const ITEMS: &'static [$crate::Item<'static>] = &[];
71                ITEMS
72            },
73            ::core::option::Option::None,
74        )
75    };
76
77    ($( $token:tt ),* $(,)?) => {
78        $crate::__template_impl!($( $token ),* ; ::core::option::Option::None)
79    };
80
81    ($( $token:tt ),* $(,)? ; $default:expr) => {
82        $crate::__template_impl!($( $token ),* ; ::core::option::Option::Some($default))
83    };
84}
85
86#[cfg(test)]
87mod tests {
88    use crate::{template, Item, Template};
89
90    #[test]
91    fn test_template2() {
92        assert_eq!(template!(), Template::new(&[], None),);
93
94        // Only literals
95        assert_eq!(template!("1"), Template::new(&[Item::Text("1")], None));
96
97        assert_eq!(
98            template!("1", "2"),
99            Template::new(&[Item::Text("1"), Item::Text("2")], None)
100        );
101
102        assert_eq!(
103            template!("1", "2", "3"),
104            Template::new(&[Item::Text("1"), Item::Text("2"), Item::Text("3")], None)
105        );
106
107        // Only keys
108        assert_eq!(template!({ "k1" }), Template::new(&[Item::Key("k1")], None));
109
110        assert_eq!(
111            template!({ "k1" }, { "k2" }),
112            Template::new(&[Item::Key("k1"), Item::Key("k2")], None)
113        );
114
115        assert_eq!(
116            template!({ "k1" }, { "k2" }, { "k3" }),
117            Template::new(&[Item::Key("k1"), Item::Key("k2"), Item::Key("k3")], None)
118        );
119
120        // Mixed
121        assert_eq!(
122            template!("1", { "k1" }, "3"),
123            Template::new(&[Item::Text("1"), Item::Key("k1"), Item::Text("3")], None)
124        );
125
126        assert_eq!(
127            template!("1", "2", { "k1" }, "3", "4"),
128            Template::new(
129                &[
130                    Item::Text("1"),
131                    Item::Text("2"),
132                    Item::Key("k1"),
133                    Item::Text("3"),
134                    Item::Text("4")
135                ],
136                None
137            )
138        );
139
140        assert_eq!(
141            template!("1", "2", { "k1" }, { "k2" }, "3", "4", { "k3" }),
142            Template::new(
143                &[
144                    Item::Text("1"),
145                    Item::Text("2"),
146                    Item::Key("k1"),
147                    Item::Key("k2"),
148                    Item::Text("3"),
149                    Item::Text("4"),
150                    Item::Key("k3"),
151                ],
152                None
153            )
154        );
155    }
156}