3个不稳定版本
0.2.0 | 2024年7月18日 |
---|---|
0.1.1 | 2024年3月14日 |
0.1.0 | 2024年3月13日 |
#189 in 过程宏
每月 126 次下载
50KB
926 行
扩展散列语法的宏。
spread!
扩展散列/结构体更新语法,允许从不同类型的结构体中获取字段,只要列出的字段在两个结构体中都具有相同的类型。它支持修饰符前缀,允许执行常见的转换,如克隆、转换、取引用;甚至可以通过提供函数路径来执行自定义转换。
use spread_macros::spread;
struct Foo {
one: String,
two: u32,
three: u32,
four: &'static str,
}
struct Bar<'a> {
one: String,
two: u64,
three: &'a u32,
four: String,
}
let foo = Foo {
one: "Hello".to_string(),
two: 2,
three: 3,
four: "HELLO",
};
let two = 2u32;
let bar = spread!(Bar {
>two, // calls .into()
{
+one, // calls .clone()
&three, // takes a reference
[str::to_lowercase] four,
} in &foo,
});
anon!
使用提供的字段生成匿名结构体的值,其类型是推断的。可以用于将多个变量捆绑在一个结构体中,然后用于 spread!
。它支持与 spread!
相同的功能(列表和修饰符),但除外最后的结构体更新语法。
use spread_macros::anon;
struct Foo {
one: String,
two: u32,
three: u32,
}
let foo = Foo {
one: "Hello".to_string(),
two: 2,
three: 3,
};
let four = 4u32;
// Creates an anonymous struct with the given fields.
let exemple = anon! {
{ +one, >two, &three } in &foo,
four,
};
// When using `>` (into) the field must be used for its type to be inferred.
let inferred: u64 = exemple.two;
println!("{exemple:?})");
slet!
通过列出所有标识符和转换,与 anon!
使用相同的语法来避免编写大量的转换,如 let variable_with_long_name = variable_with_long_name.clone()
(这在闭包和异步块中很常见)通过列出所有标识符和转换。此外,每个字段名都可以由 mut
(在潜在的修饰符之前)前缀,以创建一个 let mut
绑定。
use spread_macros::slet;
let foo = "Hello".to_string();
let bar = 42u32;
slet! {mut +foo, >bar};
let inferred: u64 = bar;
fn_struct!
生成表示给定函数或方法参数的结构体,允许使用Rust的结构体更新语法、spread!
和 Default
与函数参数。列出的字段可以使用 spread!
的修饰符,如 &
,例如,可以使用没有引用的结构体来调用具有引用参数的函数,从而实现 Default
。该结构体可以泛型化函数参数的类型,而 call
函数也可以泛型化不在参数中出现的类型。
该宏旨在在编写测试时使用,其中频繁调用具有许多参数的函数,并且可以使用 spread!
重复应用参数。
断言提供的某些字段与期望匹配。
use spread_macros::fn_struct;
fn foo(foo: u32, bar: u32, baz: &u32) -> u32 {
foo + bar + baz
}
fn_struct!(
struct Foo
for fn foo(
one: u32 = 1,
>two: u16 = 2, // converts from struct's u16 to functions u32
&three: u32 = 3 // struct stores value, function takes reference
) -> u32
);
let res = Foo {
three: 33,
..Default::default()
}
.call();
assert_eq!(res, 1 + 2 + 33);
assert_fields_eq!
这种期望可以用两种方式表达
- 可以提供另一个值,然后是一个列表,其中包含两个值共有的字段,并且这些字段应该相等。
- 一个匿名结构体,其语法与
anon!
相同。
之后,宏接受一个自定义的 panic 消息,其格式化方式与 assert_eq!
相似。
它使用作用域内的 assert_eq!
宏,允许在需要时使用替代宏,如 similar_asserts::assert_eq!
。
use spread_macros::{anon, assert_fields_eq};
#[derive(Clone, Debug)]
struct Exemple {
_foo: u32,
bar: String,
baz: bool,
}
let exemple = Exemple {
_foo: 42,
bar: String::from("exemple"),
baz: true,
};
let expected = anon! {
bar: String::from("exemple"),
baz: true,
other: "other",
};
assert_fields_eq!(exemple, {
bar: String::from("exemple"),
{ +baz } in &expected,
});
assert_fields_eq!(
exemple,
expected,
[bar, baz],
"unexpected fields in {exemple:?}"
);
依赖项
~275–730KB
~17K SLoC