cfgmap/
macros.rs

1// PUBLIC MACROS
2
3#[macro_export]
4/// Creates a `CfgValue` value using the passed variable.
5///
6/// ## Examples:
7/// ```
8/// # use cfgmap::{CfgMap, Condition::*, Checkable, value};
9/// let s = value!(4);
10/// let x = value!(3.2);
11/// let y = value!("hello there");
12/// let a = value!(vec![value!(3), value!(9.4), value!("amazing")]);
13/// let m = value!(CfgMap::new());
14///
15/// assert!(s.check_that(IsInt));
16/// assert!(x.check_that(IsFloat));
17/// assert!(y.check_that(IsStr));
18/// assert!(a.check_that(IsListWith(Box::new(IsInt | IsFloat | IsStr))));
19/// assert!(m.check_that(IsMap));
20/// ```
21macro_rules! value {
22    ($($tt:tt)*) => {
23        {
24            let __value: $crate::CfgValue = ($($tt)*).into();
25            __value
26        }
27    };
28}
29
30#[macro_export]
31/// Creates a `CfgValue::List` from the values passed.
32/// Works very similarly to the `vec!` macro.
33///
34/// ## Examples:
35/// ```
36/// # use cfgmap::{Condition::*, Checkable, value, list};
37/// let arr1 = list![2, 3.2, "hello there"];
38/// let arr2 = value!(vec![value!(2), value!(3.2), value!("hello there")]);
39///
40/// assert_eq!(arr1, arr2);
41/// ```
42macro_rules! list {
43    ($($tt:tt),*) => {
44        value!(vec![$(value!($tt)),*])
45    };
46}
47
48// MACROS for implementing FROM trait.
49
50macro_rules! from_int {
51    ($($type:ty),*) => {
52        $(
53        impl From<$type> for CfgValue {
54            fn from(i: $type) -> Self {
55                CfgValue::Int(i.into())
56            }
57        }
58        )*
59    };
60}
61
62macro_rules! from_float {
63    ($($type:ty),*) => {
64        $(
65        impl From<$type> for CfgValue {
66            fn from(f: $type) -> Self {
67                CfgValue::Float(f.into())
68            }
69        }
70        )*
71    };
72}
73
74macro_rules! from_str {
75    ($($type:ty),*) => {
76        $(
77        impl From<$type> for CfgValue {
78            fn from(s: $type) -> Self {
79                CfgValue::Str(s.into())
80            }
81        }
82        )*
83    };
84}
85
86// MACROS for documenting, and implementing "is", "as" and "as_mut".
87
88macro_rules! doc_comment {
89    ($x:expr, $($tt:tt)*) => {
90        #[doc = $x]
91        $($tt)*
92    };
93}
94
95macro_rules! is_type {
96    ($fn_name:ident, $enum_type:path) => {
97        doc_comment! {
98            concat!("Checks whether the enum is a `", stringify!($enum_type), "`."),
99            pub fn $fn_name (&self) -> bool {
100                if let $enum_type(..) = self {
101                    true
102                } else { false }
103            }
104        }
105    };
106
107    ($fn_name:ident [0], $enum_type:path) => {
108        doc_comment! {
109            concat!("Checks whether the enum is a `", stringify!($enum_type), "`."),
110            pub fn $fn_name (&self) -> bool {
111                if let $enum_type = self {
112                    true
113                } else { false }
114            }
115        }
116    }
117}
118
119macro_rules! as_type {
120    ($fn_name:ident, $type:ty, $enum_type:path) => {
121        doc_comment! {
122            concat!("Returns a reference to the `", stringify!($type),
123                    "`. Result is `None` if contents aren't a `", stringify!($enum_type), "`."),
124            pub fn $fn_name (&self) -> Option<&$type> {
125                if let $enum_type(x) = self {
126                    Some(x)
127                } else { None }
128            }
129        }
130    };
131}
132
133macro_rules! as_mut_type {
134    ($fn_name:ident, $type:ty, $enum_type:path) => {
135        doc_comment! {
136            concat!("Returns a reference to the `", stringify!($type),
137                    "`. Result is `None` if contents aren't a `", stringify!($enum_type), "`."),
138            pub fn $fn_name (&mut self) -> Option<&mut $type> {
139                if let $enum_type(x) = self {
140                    Some(x)
141                } else { None }
142            }
143        }
144    };
145}