1#[macro_export(local_inner_macros)]
76macro_rules! value {
77 ($($tt:tt)*) => {
78 value_internal!($($tt)*)
79 };
80}
81
82#[macro_export(local_inner_macros)]
107#[doc(hidden)]
108macro_rules! value_internal {
109
110 (@unnamed [$($e:expr, )*] ()) => { vec_wrapper![$($e, )*] };
116
117 (@unnamed [$($e:expr, )*] (($($array:tt)*) $($rest:tt)*)) => {
119 value_internal!(@unnamed [$($e, )*] (value_internal!(($($array)*))) $($rest)*)
120 };
121
122 (@unnamed [$($e:expr, )*] ($variant:ident ($($array:tt)*) $($rest:tt)*)) => {
124 value_internal!(@unnamed [$($e, )*] (value_internal!($variant ($($array)*))) $($rest)*)
125 };
126
127 (@unnamed [$($e:expr, )*] ({$($map:tt)*} $($rest:tt)*)) => {
129 value_internal!(@unnamed [$($e, )*] (value_internal!({$($map)*})) $($rest)*)
130 };
131
132 (@unnamed [$($e:expr, )*] ($variant:ident {$($map:tt)*} $($rest:tt)*)) => {
134 value_internal!(@unnamed [$($e, )*] (value_internal!($variant {$($map)*})) $($rest)*)
135 };
136
137 (@unnamed [$($e:expr, )*] ($value:expr) , $($rest:tt)*) => {
139 value_internal!(@unnamed [$($e, )* $value , ] ($($rest)*))
140 };
141
142 (@unnamed [$($e:expr, )*] ($value:expr) $unexpected:tt $($rest:tt)*) => {
145 let token = core::stringify!($unexpected);
146 compile_error!("unexpected token after expression: {}", token);
147 };
148
149 (@unnamed [$($e:expr, )*] ($value:expr)) => {
151 vec_wrapper![ $($e, )* value_internal!($value) ]
152 };
153
154 (@unnamed [$($e:expr, )*] ($value:expr , $($rest:tt)*)) => {
156 value_internal!(@unnamed [$($e, )*] (value_internal!($value)) , $($rest)*)
157 };
158
159 (@named [$(($k:expr, $v:expr), )*] () ()) => { vec_wrapper![ $(($k, $v), )* ] };
165
166 (@named [$(($k:expr, $v:expr), )*] [$key:expr] ($value:expr) , $($rest:tt)*) => {
168 {
169 let field_name = literal_aware_stringify!($key);
170 value_internal!(@named [$(($k, $v), )* (field_name, $value), ] () ($($rest)*))
171 }
172 };
173
174 (@named [$(($k:expr, $v:expr), )*] [$key:expr] ($value:expr) $unexpected:tt $($rest:tt)*) => {
177 let token = core::stringify!($unexpected);
178 compile_error!("unexpected token after expression: {}", token);
179 };
180
181 (@named [$(($k:expr, $v:expr), )*] [$key:expr] ($value:expr)) => {
183 {
184 let field_name = literal_aware_stringify!($key);
185 vec_wrapper![ $(($k, $v), )* (field_name, $value) ]
186 }
187 };
188
189 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (: ($($array:tt)*) $($rest:tt)*)) => {
191 value_internal!(@named [$(($k, $v), )*] [$key] (value_internal!(($($array)*))) $($rest)*)
192 };
193
194 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (: $variant:ident ($($array:tt)*) $($rest:tt)*)) => {
196 value_internal!(@named [$(($k, $v), )*] [$key] (value_internal!($variant ($($array)*))) $($rest)*)
197 };
198
199 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (: {$($map:tt)*} $($rest:tt)*)) => {
201 value_internal!(@named [$(($k, $v), )*] [$key] (value_internal!({$($map)*})) $($rest)*)
202 };
203
204 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (: $variant:ident {$($map:tt)*} $($rest:tt)*)) => {
206 value_internal!(@named [$(($k, $v), )*] [$key] (value_internal!($variant {$($map)*})) $($rest)*)
207 };
208
209 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (: $value:expr , $($rest:tt)*)) => {
211 value_internal!(@named [$(($k, $v), )*] [$key] (value_internal!($value)) , $($rest)*)
212 };
213
214 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (: $value:expr)) => {
216 value_internal!(@named [$(($k, $v), )*] [$key] (value_internal!($value)))
217 };
218
219 (@named [$(($k:expr, $v:expr), )*] ($key:expr) (:)) => {
221 compile_error!("missing value for last entry");
222 };
223
224 (@named [$(($k:expr, $v:expr), )*] ($key:expr) ()) => {
226 compile_error!("missing colon and value for last entry");
227 };
228
229 (@named [$(($k:expr, $v:expr), )*] () (: $($rest:tt)*)) => {
231 compile_error!("colon in wrong position");
232 };
233
234 (@named [$(($k:expr, $v:expr), )*] ($($key:tt)*) (, $($rest:tt)*)) => {
236 compile_error!("comma in key of named composite");
237 };
238
239 (@named [$(($k:expr, $v:expr), )*] () (($key:expr) : $($rest:tt)*)) => {
240 value_internal!(@named [$(($k, $v), )*] ($key) (: $($rest)*))
241 };
242
243 (@named [$(($k:expr, $v:expr), )*] ($($key:tt)*) ($tt:tt $($rest:tt)*)) => {
245 value_internal!(@named [$(($k, $v), )*] ($($key)* $tt) ($($rest)*))
246 };
247
248 () => {
254 $crate::Value::unnamed_composite(Vec::<$crate::Value>::new())
255 };
256 (()) => {
257 $crate::Value::unnamed_composite(Vec::<$crate::Value>::new())
258 };
259 ({}) => {
260 $crate::Value::named_composite(Vec::<(String, $crate::Value)>::new())
261 };
262
263 ({ $($tt:tt)* }) => {
265 {
266 let fields: Vec::<(String, $crate::Value)> = value_internal!(@named [] () ($($tt)*));
267 $crate::Value::named_composite(fields)
268 }
269 };
270
271 ($variant:ident { $($tt:tt)* }) => {
273 {
274 let variant_name = literal_aware_stringify!($variant);
275 let fields: Vec::<(String, $crate::Value)> = value_internal!(@named [] () ($($tt)*));
276 $crate::Value::named_variant(variant_name,fields)
277 }
278 };
279
280 (( $($tt:tt)* )) => {
282 {
283 let fields = value_internal!(@unnamed [] ($($tt)*));
284 $crate::Value::unnamed_composite(fields)
285 }
286 };
287
288 ($variant:ident ( $($tt:tt)* )) => {
290 {
291 let variant_name = literal_aware_stringify!($variant);
292 let fields = value_internal!(@unnamed [] ($($tt)*));
293 $crate::Value::unnamed_variant(variant_name,fields)
294 }
295 };
296
297 ($val:expr) => {
299 $crate::Value::from($val)
300 };
301}
302
303#[macro_export]
306#[doc(hidden)]
307macro_rules! vec_wrapper {
308 ($($content:tt)*) => {
309 vec![$($content)*]
310 };
311}
312
313#[macro_export]
316#[doc(hidden)]
317macro_rules! literal_aware_stringify {
318 ($tt:literal) => {
319 $tt.to_string()
320 };
321 ($($tt:tt)*) => {
322 stringify!($($tt)*).to_string()
323 };
324}
325
326#[cfg(test)]
327#[macro_use]
328mod test {
329 use crate::prelude::*;
330 use crate::{value, Value};
331
332 #[test]
333 fn macro_tests() {
334 assert_eq!(value!(1), Value::from(1));
336 assert_eq!(value!(-122193223i64), Value::from(-122193223i64));
337 assert_eq!(value!(89usize), Value::from(89usize));
338 assert_eq!(value!(false), Value::from(false));
339 assert_eq!(value!(true), Value::from(true));
340 assert_eq!(value!('h'), Value::from('h'));
341 assert_eq!(value!("Hello"), Value::from("Hello"));
342 assert_eq!(value!("Hello".to_string()), Value::from("Hello"));
343 let s = "Hello".to_string();
344 assert_eq!(value!(s), Value::from("Hello"));
345
346 let unnamed_composite =
348 Value::unnamed_composite([Value::from(1), Value::from("nice"), Value::from('t')]);
349
350 assert_eq!(value!((1, "nice", 't')), unnamed_composite);
351 assert_eq!(value!((1, "nice", 't',)), unnamed_composite);
352
353 let empty_composite = Value::unnamed_composite([]);
354 assert_eq!(value!(()), empty_composite);
355
356 let named_composite =
358 Value::named_composite([("num", Value::from(3)), ("item", Value::from("tea"))]);
359 assert_eq!(value!({num: 3, item: "tea"}), named_composite);
360 assert_eq!(value!({num: 3, item: "tea", }), named_composite);
361 let variant_no_fields = Value::variant("v1", crate::Composite::Unnamed(vec![]));
363 assert_eq!(value!(v1()), variant_no_fields);
364 let named_variant = Value::variant(
365 "V2",
366 crate::Composite::named([("num", Value::from(3)), ("item", Value::from("tea"))]),
367 );
368 assert_eq!(value!(V2 { num: 3, item: "tea" }), named_variant);
369 let value = value!({ "string key": 123 });
371 assert_eq!(value, Value::named_composite([("string key", Value::from(123))]));
372 let _ = value!({ unnamed: unnamed_composite, vals: (v1{name: "berry", age: 34}, named_variant), named: named_composite });
374 }
375}