macro_rules! manipulate {
{ @CALL [ $($f:tt)* ] [ $($value:expr),* ] } => { ... };
{
@CALL
$f:tt
$value:tt => $args:tt
} => { ... };
{ // 终态:插入完成
@INSERT
[ $($f:tt)* ]
$_value:tt =>
[
$( $values:expr ),*
$(,)?
]
} => { ... };
{ // 中态:不断插入
@INSERT
$f:tt
[ $value:expr ] =>
[
$( $value_past:expr, )*
_
$( $tail:tt )*
]
} => { ... };
{ @MANIPULATE $value:expr } => { ... };
{ &mut $value:expr => $( $tail:tt )+ } => { ... };
{ $value:expr => $( $tail:tt )+ } => { ... };
{
@MANIPULATE
$value:expr =>
#{ $($prefix:tt)* }
$( => $($tail:tt)*)?
} => { ... };
{
@MANIPULATE
$value:expr =>
{ $($suffix:tt)* }#
$( => $($tail:tt)*)?
} => { ... };
{
@MANIPULATE
$value:expr =>
. $key:tt $( ( $($param:tt)* ) )?
$( => $($tail:tt)*)?
} => { ... };
{
@MANIPULATE
$value:expr =>
[ $($dot_path:tt).+ ] $( ( $($param:tt)* ) )?
$( => $($tail:tt)*)?
} => { ... };
{
@MANIPULATE
$value:expr =>
$($p:tt)::+ $( ( $($param:tt)* ) )?
$( => $($tail:tt)*)?
} => { ... };
{
@MANIPULATE
$value:expr =>
($f:expr) $( ( $($param:tt)* ) )?
$( => $($tail:tt)*)?
} => { ... };
}Expand description
§manipulate!
一个实用、强大而高效的「操作」宏,允许对值进行流式操作并返回自身
- 🎯用以简化「创建值,对值进行操作,最后返回值」的模板代码
- 📄初始化集合、[
HashMap]等数据类型
- 📄初始化集合、[
! 🚩严格区分「按值传入的参数」与「按可变引用传入的参数」
- 📌【2024-04-02 02:53:17】目前默认均使用「可变引用」进行插值
- 📄对于「输入所有权,返回所有权」推荐使用
pipe
§📄示例 Examples
use nar_dev_utils::{asserts, manipulate, pipe};
// 示例/数值 //
let n = manipulate!(
2
=> {+= 1}# // 后缀语法 => `2 += 1`
=> {-= 2}#
);
assert_eq!(n, 1);
// 示例/字符串 //
let s = manipulate! (
String::new() // 创建一个字符串,并在下方进行操作
=> .push_str("foo") // 向字符串添加字符切片
=> .push('b') // 向字符串添加字符
=> .push('a') // 向字符串添加字符
=> .push('r') // 再向字符串添加字符
=> { += "无效"}# // 向字符串添加字串切片(附加运算符)
=> .split_off(6) // 抛出索引`6`以外的字符串,并消耗它
); // 最后返回修改后的字符串
assert_eq!(s, "foobar");
// 示例/双端队列 | 主要展示**用法** //
use std::collections::VecDeque;
let pop_front = VecDeque::pop_front;
fn back_push<T>(x: T, s: &mut VecDeque<T>) {
s.push_back(x)
}
let v = manipulate! (
VecDeque::new()
=> VecDeque::push_front(_, 0) // 关联函数调用+插值
=> back_push(1, _) // 不同位置的插值 | ⚠️可变引用不可能双重插值
=> .insert(1, 2) // 方法调用
=> pop_front // 函数变量调用
=> VecDeque::pop_back // 关联函数调用,带路径
=> ({
// 可以在此执行代码
type Vdq<T> = VecDeque<T>;
|v: &mut Vdq<_>| v.remove(1) // 允许使用闭包进行操作
})
);
// 整个流程:[] => [0] => [0, 1] => [0, 2, 1] => [2, 1] => [2] => [2]
assert_eq!(v, [2]);
// 示例/集合 //
use std::collections::HashSet;
let set = manipulate! (
HashSet::new() // 创建集合
=> .insert(3) // 集合填入`3`
=> .insert(2) // 集合填入`2`
=> .insert(1) // 集合填入`1`
);
asserts! {
manipulate!(
pipe! {
set // 引入集合,进行管道操作
=> .iter() // 迭代器
=> .cloned() // 复制
=> {.collect::<Vec<_>>()}# // 收集
}
// 数组排序(从小到大)
=> .sort()
) // ↓检验相等
=> [1, 2, 3],
// 集合的相等,证明顺序无关
set => manipulate! (
HashSet::new() // 创建集合
=> .insert(1) // 集合填入`1`
=> .insert(2) // 集合填入`2`
=> .insert(3) // 集合填入`3`
)
}