manipulate

Macro manipulate 

Source
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`
    )
}