macro_rules! value {
($($value:tt)+) => { ... };
}recursive only.Expand description
Construct a Value from a Rust-like constructor expression.
With this macro it is possible to construct values that have the same structure as actual types like structs, enums, tuples, or even primitive types. It is not necessary to declare the types in advance.
§Syntax
The syntax is more or less the same as Rust’s constructor expressions for
structs, enums, and tuples. The name of structs can be omitted. Enum
variants must be written in the form Foo::Bar (specifying only the
variant is not supported, even if the variant is imported).
Literals for bool, char, number, and strings can be written similar to Rust
literals with some minor differences: a &str does not have to be converted
to a String (this is done automatically), and brackets are used for
sequences, not arrays. Each number literal should contain the type, e.g.,
42_u64, 1.2_f32, etc. This is necessary because the macro cannot infer
the type of number literals.
The following example gives an overview of the syntax, with elements of various types.
use asserting::prelude::*;
let value = value!({ // a struct
foo: 2.3_f64, // a float literal
bar: { // an embedded struct
baz: "alpha", // a string literal
qux: 123_i16, // an integer literal
corge: true, // a boolean literal
},
grault: Sample::Two("beta", -456_i64), // a tuple variant
waldo: (123_u8, 234_u8, 56_u8), // a tuple
fred: ["alpha", "beta", "gamma"], // a sequence
quux: #{ 'a' => 1, 'b' => 2, 'c' => 3}, // a map
thud: Named(0.8_f32), // a tuple struct
});Variables in scope can be referenced inside the value!-macro.
use asserting::prelude::*;
let one = 1;
let two = 2;
let three = 3;
let value = value!([one, two, three]);
assert_eq!(format!("{value:?}"), "[1, 2, 3]");Expressions can be used inside the value!-macro as well:
use asserting::prelude::*;
let value = value!(Sum(13_i16 + 17_i16));
assert_eq!(format!("{value:?}"), "Sum(30)");§Structs
Structs can be constructed on the fly, without prior declaration of a type.
In asserting they are called “anonymous structs”. The name of a struct
can be omitted.
let value = value!({
name: "Silvia",
age: 25_u8,
});The name of a struct to be constructed can be specified as by the usual syntax in Rust.
let value = value!(Person {
name: "Silvia",
age: 25_u8,
});Note: The name of a struct is not compared in the field-by-field recursive comparison mode.
§Tuples
A tuple is constructed using parenthesis as in plain Rust.
let value = value!((42_u64, "alpha", true));§Enums-Variants
Example for constructing a value of unit variant:
let value = value!(Foo::Bar);Example for constructing a value of tuple variant:
let value = value!(Foo::Bar(-1.3_f32));Example for constructing a value of struct variant:
let value = value!(Foo::Bar { left: "alpha", right: -123_i16 });§Sequences
A sequence is constructed by enclosing a list of values inside brackets. In the following example we construct a sequence of chars.
let value = value!(['a', 'b', 'c']);§Maps
A map starts with #{ and ends with }. An association between a key and
a value is separated by =>. Multiple key/value-pairs are separated by ,.
let value = value!(#{
'a' => 1,
'b' => 2,
'c' => 3,
});§Primitive types
| Type | Example |
|---|---|
bool | true or false |
char | 'a' |
f32 | 1.2_f32 |
f64 | 1.2_f64 |
str | "alpha" |
String | "alpha" |
i8 | -12_i8 |
i16 | -12_i16 |
i32 | -12_i32 |
i64 | -12_i64 |
i128 | -12_i128 |
u8 | 12_i8 |
u16 | 12_i16 |
u32 | 12_i32 |
u64 | 12_i64 |
u128 | 12_i128 |
Note: isize and usize are not supported by serde. Therefore, isize
values are converted to i64 or i128 and usize values are converted to
u64 or u128.
§Limitations
§No Field Init Shorthand
When initializing a struct field with the value of a variable, the field init shorthand is not supported. Even if the field has the same name as the variable, the variable must be repeated after the colon.
Instead of using the field init shorthand, which does not compile:
use asserting::prelude::*;
let bar = "alpha";
let value = value!(Foo { bar });using the normal (verbose) syntax works:
use asserting::prelude::*;
let bar = "alpha";
let value = value!(Foo { bar: bar });
assert_eq!(value, value!(Foo { bar: "alpha" }));§No Unit Structs
This macro does not support unit structs. Unit structs interfere with identifiers captured from the environment. We decided that capturing variables from the environment of the macro is more valuable than unit structs.