1#[macro_export(local_inner_macros)]
42macro_rules! value {
43 ($($tt:tt)*) => {
44 value_internal!($($tt)*)
45 };
46}
47
48#[macro_export(local_inner_macros)]
73#[doc(hidden)]
74macro_rules! value_internal {
75
76 (@unnamed [$($e:expr, )*] ()) => { vec_wrapper![$($e, )*] };
82
83 (@unnamed [$($e:expr, )*] (($($array:tt)*) $($rest:tt)*)) => {
85 value_internal!(@unnamed [$($e, )*] (value_internal!(($($array)*))) $($rest)*)
86 };
87
88 (@unnamed [$($e:expr, )*] ($variant:ident ($($array:tt)*) $($rest:tt)*)) => {
90 value_internal!(@unnamed [$($e, )*] (value_internal!($variant ($($array)*))) $($rest)*)
91 };
92
93 (@unnamed [$($e:expr, )*] ({$($map:tt)*} $($rest:tt)*)) => {
95 value_internal!(@unnamed [$($e, )*] (value_internal!({$($map)*})) $($rest)*)
96 };
97
98 (@unnamed [$($e:expr, )*] ($variant:ident {$($map:tt)*} $($rest:tt)*)) => {
100 value_internal!(@unnamed [$($e, )*] (value_internal!($variant {$($map)*})) $($rest)*)
101 };
102
103 (@unnamed [$($e:expr, )*] ($value:expr) , $($rest:tt)*) => {
105 value_internal!(@unnamed [$($e, )* $value , ] ($($rest)*))
106 };
107
108 (@unnamed [$($e:expr, )*] ($value:expr) $unexpected:tt $($rest:tt)*) => {
111 let token = core::stringify!($unexpected);
112 compile_error!("unexpected token after expression: {}", token);
113 };
114
115 (@unnamed [$($e:expr, )*] ($value:expr)) => {
117 vec_wrapper![ $($e, )* value_internal!($value) ]
118 };
119
120 (@unnamed [$($e:expr, )*] ($value:expr , $($rest:tt)*)) => {
122 value_internal!(@unnamed [$($e, )*] (value_internal!($value)) , $($rest)*)
123 };
124
125 (@named [$(($k:expr, $v:expr), )*] () ()) => { vec_wrapper![ $(($k, $v), )* ] };
131
132 (@named [$(($k:expr, $v:expr), )*] [$key:expr] ($value:expr) , $($rest:tt)*) => {
134 {
135 let field_name = literal_aware_stringify!($key);
136 value_internal!(@named [$(($k, $v), )* (field_name, $value), ] () ($($rest)*))
137 }
138 };
139
140 (@named [$(($k:expr, $v:expr), )*] [$key:expr] ($value:expr) $unexpected:tt $($rest:tt)*) => {
143 let token = core::stringify!($unexpected);
144 compile_error!("unexpected token after expression: {}", token);
145 };
146
147 (@named [$(($k:expr, $v:expr), )*] [$key:expr] ($value:expr)) => {
149 {
150 let field_name = literal_aware_stringify!($key);
151 vec_wrapper![ $(($k, $v), )* (field_name, $value) ]
152 }
153 };
154
155 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (: ($($array:tt)*) $($rest:tt)*)) => {
157 value_internal!(@named [$(($k, $v), )*] [$key] (value_internal!(($($array)*))) $($rest)*)
158 };
159
160 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (: $variant:ident ($($array:tt)*) $($rest:tt)*)) => {
162 value_internal!(@named [$(($k, $v), )*] [$key] (value_internal!($variant ($($array)*))) $($rest)*)
163 };
164
165 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (: {$($map:tt)*} $($rest:tt)*)) => {
167 value_internal!(@named [$(($k, $v), )*] [$key] (value_internal!({$($map)*})) $($rest)*)
168 };
169
170 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (: $variant:ident {$($map:tt)*} $($rest:tt)*)) => {
172 value_internal!(@named [$(($k, $v), )*] [$key] (value_internal!($variant {$($map)*})) $($rest)*)
173 };
174
175 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (: $value:expr , $($rest:tt)*)) => {
177 value_internal!(@named [$(($k, $v), )*] [$key] (value_internal!($value)) , $($rest)*)
178 };
179
180 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (: $value:expr)) => {
182 value_internal!(@named [$(($k, $v), )*] [$key] (value_internal!($value)))
183 };
184
185 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (:)) => {
187 compile_error!("missing value for last entry");
188 };
189
190 (@named [$(($k:expr, $v:expr), )*] ($key:expr) ()) => {
192 compile_error!("missing colon and value for last entry");
193 };
194
195 (@named [$(($k:expr, $v:expr), )*] () (: $($rest:tt)*)) => {
197 compile_error!("colon in wrong position");
198 };
199
200 (@named [$(($k:expr, $v:expr), )*] ($($key:tt)*) (, $($rest:tt)*)) => {
202 compile_error!("comma in key of named composite");
203 };
204
205 (@named [$(($k:expr, $v:expr), )*] () (($key:expr) : $($rest:tt)*)) => {
206 value_internal!(@named [$(($k, $v), )*] ($key) (: $($rest)*))
207 };
208
209 (@named [$(($k:expr, $v:expr), )*] ($($key:tt)*) ($tt:tt $($rest:tt)*)) => {
211 value_internal!(@named [$(($k, $v), )*] ($($key)* $tt) ($($rest)*))
212 };
213
214 () => {
220 $crate::Value::unnamed_composite(Vec::<$crate::Value>::new())
221 };
222 (()) => {
223 $crate::Value::unnamed_composite(Vec::<$crate::Value>::new())
224 };
225 ({}) => {
226 $crate::Value::named_composite(Vec::<(String, $crate::Value)>::new())
227 };
228
229 ({ $($tt:tt)* }) => {
231 {
232 let fields: Vec::<(String, $crate::Value)> = value_internal!(@named [] () ($($tt)*));
233 $crate::Value::named_composite(fields)
234 }
235 };
236
237 ($variant:ident { $($tt:tt)* }) => {
239 {
240 let variant_name = literal_aware_stringify!($variant);
241 let fields: Vec::<(String, $crate::Value)> = value_internal!(@named [] () ($($tt)*));
242 $crate::Value::named_variant(variant_name,fields)
243 }
244 };
245
246 (( $($tt:tt)* )) => {
248 {
249 let fields = value_internal!(@unnamed [] ($($tt)*));
250 $crate::Value::unnamed_composite(fields)
251 }
252 };
253
254 ($variant:ident ( $($tt:tt)* )) => {
256 {
257 let variant_name = literal_aware_stringify!($variant);
258 let fields = value_internal!(@unnamed [] ($($tt)*));
259 $crate::Value::unnamed_variant(variant_name,fields)
260 }
261 };
262
263 ($val:expr) => {
265 $crate::Value::from($val)
266 };
267}
268
269#[macro_export]
272#[doc(hidden)]
273macro_rules! vec_wrapper {
274 ($($content:tt)*) => {
275 vec![$($content)*]
276 };
277}
278
279#[macro_export]
282#[doc(hidden)]
283macro_rules! literal_aware_stringify {
284 ($tt:literal) => {
285 $tt.to_string()
286 };
287 ($($tt:tt)*) => {
288 stringify!($($tt)*).to_string()
289 };
290}
291
292#[cfg(test)]
293#[macro_use]
294mod test {
295 use crate::prelude::*;
296 use crate::{value, Value};
297
298 #[test]
299 fn macro_tests() {
300 assert_eq!(value!(1), Value::from(1));
302 assert_eq!(value!(-122193223i64), Value::from(-122193223i64));
303 assert_eq!(value!(89usize), Value::from(89usize));
304 assert_eq!(value!(false), Value::from(false));
305 assert_eq!(value!(true), Value::from(true));
306 assert_eq!(value!('h'), Value::from('h'));
307 assert_eq!(value!("Hello"), Value::from("Hello"));
308 assert_eq!(value!("Hello".to_string()), Value::from("Hello"));
309 let s = "Hello".to_string();
310 assert_eq!(value!(s), Value::from("Hello"));
311
312 let unnamed_composite =
314 Value::unnamed_composite([Value::from(1), Value::from("nice"), Value::from('t')]);
315
316 assert_eq!(value!((1, "nice", 't')), unnamed_composite);
317 assert_eq!(value!((1, "nice", 't',)), unnamed_composite);
318
319 let empty_composite = Value::unnamed_composite([]);
320 assert_eq!(value!(()), empty_composite);
321
322 let named_composite =
324 Value::named_composite([("num", Value::from(3)), ("item", Value::from("tea"))]);
325 assert_eq!(value!({num: 3, item: "tea"}), named_composite);
326 assert_eq!(value!({num: 3, item: "tea", }), named_composite);
327 let variant_no_fields = Value::variant("v1", crate::Composite::Unnamed(vec![]));
329 assert_eq!(value!(v1()), variant_no_fields);
330 let named_variant = Value::variant(
331 "V2",
332 crate::Composite::named([("num", Value::from(3)), ("item", Value::from("tea"))]),
333 );
334 assert_eq!(value!(V2 { num: 3, item: "tea" }), named_variant);
335 let value = value!({ "string key": 123 });
337 assert_eq!(value, Value::named_composite([("string key", Value::from(123))]));
338 let _ = value!({ unnamed: unnamed_composite, vals: (v1{name: "berry", age: 34}, named_variant), named: named_composite });
340 }
341}