urlqstring/
macros.rs

1
2/// Construct a `QueryParams` from a Js object-like literal.
3///
4/// ```rust
5/// use urlqstring::proto_object;
6/// let value = proto_object!({
7///     "rust": "A sytem language",
8///     "python": "A script language",
9///     "apple": "A fruit"
10/// });
11/// ```
12///
13/// Variables or expressions can be inserted into the object-like literal.
14/// ```rust
15/// use urlqstring::proto_object;
16///
17/// let rust = "A system language";
18/// let python = ["script language", "dynamic language"];
19/// let value = proto_object!({
20///     "rust": rust,
21///     "python": python
22/// });
23/// ```
24///
25/// Trailing commas are allowed inside both arrays and objects.
26/// ```rust
27/// use urlqstring::proto_object;
28///
29/// let value = proto_object!({
30///     "id": 1024,
31///     "name": "rust",
32///     "comma": true,
33/// });
34/// ```
35
36#[macro_export(local_inner_macros)]
37macro_rules! proto_object {
38    ($($obj:tt)+) => {
39        object_internal!($($obj)+)
40    };
41}
42
43#[macro_export(local_inner_macros)]
44#[doc(hidden)]
45macro_rules! object_internal {
46
47
48    (@array [$($elems:expr,)*]) => {
49        object_internal_vec!($($elems,)*)
50    };
51
52    (@array [$($elems:expr),*]) => {
53        object_internal_vec!($($elems),*)
54    };
55
56    (@object $object:ident () () ()) => {};
57
58    (@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => {
59        $object.push(($($key)+, $value));
60        object_internal!(@object $object () ($($rest)*) ($($rest)*));
61    };
62
63    (@object $object:ident [$($key:tt)+] ($value:expr)) => {
64        $object.push(($($key)+, $value));
65    };
66
67    (@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => {
68        object_internal!(@object $object [$($key)+] (object_single_value!(true)) $($rest)*);
69    };
70
71    (@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => {
72        object_internal!(@object $object [$($key)+] (object_single_value!(false)) $($rest)*);
73    };
74
75    (@object $object:ident ($($key:tt)+) (: $value:expr, $($rest:tt)*) $copy:tt) => {
76        object_internal!(@object $object [$($key)+] (object_single_value!($value)), $($rest)*);
77    };
78
79    (@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => {
80        object_internal!(@object $object [$($key)+] (object_single_value!($value)));
81    };
82
83    (@object $object:ident () (: $(rest:tt)*) ($colon:tt $($copy:tt)*)) => {
84        object_unexpected($colon);
85    };
86
87    (@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => {
88        object_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*));
89    };
90
91    (@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => {
92        object_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*));
93    };
94
95    ({ $($tt:tt)+ }) => {
96        {
97            let mut object = Vec::<(&str, &str)>::new();
98            object_internal!(@object object () ($($tt)+) ($($tt)+));
99            $crate::QueryParams::from( object )
100        }
101    };
102}
103
104
105#[macro_export]
106#[doc(hidden)]
107macro_rules! object_single_value {
108    (true) => {
109        "true"
110    };
111
112    (false) => {
113        "false"
114    };
115
116    ({}) => {
117        ""
118    };
119
120    ([]) => {
121        ""
122    };
123
124    ([ $(tt:tt)+ ]) => {
125        object_internal!(@array [] $($tt)+ )
126    };
127
128    ($expr:expr) => {
129        stringify!($expr).trim_matches('"')
130    }
131}
132
133#[macro_export]
134#[doc(hidden)]
135macro_rules! object_internal_vec {
136    ($($vec:tt)*) => {
137        vec![$($vec)*]
138    };
139}
140
141#[macro_export]
142#[doc(hidden)]
143macro_rules! object_unexpected {
144    () => {};
145}
146
147
148#[test]
149fn  test()
150{
151    let val = proto_object!({
152        "rust": true,
153        "lumin": [1,2,3,123],
154        "test_string": "hello",
155        "test_vec": vec!["hello","world","and","rust"],
156        }
157    );
158
159    println!("value={:?}", val);
160}
161