lwleen-rpc 1.3.3

RPC (信令路由), 组件间数据通信
Documentation
//! 🧊宏
//! 
//! - impl信令特征  
//! - core发布信令任务 
//! - cfg_if
//! - cfg_多行特性
//! - match取出

#![allow(unused_macros)]



#[macro_export]
macro_rules! anyhow_Ok信令{  ($res:expr)=>{ anyhow_Ok($res) };   }
#[macro_export]
macro_rules! anyhow_Err信令{
    ($msg:literal $(,)?)     => {  Err(anyhow_err!($msg))  };
    ($err:expr $(,)?)        => {  Err(anyhow_err!($err))  };
    ($fmt:expr, $($arg:tt)*) => {  Err(anyhow_err!($fmt, $($arg)*))  };
}




/// ### 快速生成一个信令任务
/// - 如下, 可自定义返回结果
/// ```no_run
/// fn 范例_修改返回结果(&self,参数:impl AsRef<str> )-> impl 信令任务</* 修改结果类型 */>{
///     信令表::test { one:123, two:321 }
///         .发布信令任务(self.clone(),
///             |res|{
///                 let mut 结果 = match取出!(res? ,信令表::test_回复 => one)?;
///                 Ok(/* 修改结果 */)
///         })
/// }
/// 
/// // 第二种
/// 信令路由::task发布_信令任务($ref_信令路由.to_owned(), $信令 , |结果| match取出!(结果?.try_into()?,  $enum_路径) )
/// 信令路由::task发布_信令任务($ref_信令路由.to_owned(), $信令 , |结果| match取出!(结果?.try_into()?,  $enum_路径 => $($field),+  ) )
/// 信令路由::task发布_信令任务($ref_信令路由.to_owned(), $信令 , |结果| match取出!(结果?.try_into()?,  $enum_路径 => <$($index),+> ) )
/// ```
#[macro_export]
macro_rules! core发布信令任务{
    ($ref_信令路由:expr, $信令:expr, $enum_路径:path) => {
        $信令.发布信令任务($ref_信令路由.to_owned(), |结果| match取出!(结果?,  $enum_路径))
    };
    ($ref_信令路由:expr, $信令:expr, $enum_路径:path => $($field:ident),+  ) => {
        $信令.发布信令任务($ref_信令路由.to_owned(), |结果| match取出!(结果?,  $enum_路径 => $($field),+  )  )
    };
    ($ref_信令路由:expr, $信令:expr, $enum_路径:path => <$($index:tt),+> ) => {
        $信令.发布信令任务($ref_信令路由.to_owned(), |结果| match取出!(结果?,  $enum_路径 => <$($index),+>  )  )
    };
}






/// ## 所有`信令表`必须实现此特征
/// - `信令表` > `执行函数`
/// - `信令表` > `发布信令任务`
/// ---
/// ### 范例
/// ```no_run
/// #[derive(Clone, Serialize, Deserialize)]//可选特征
/// enum 信令表{  }
/// 
/// impl信令特征!(信令表, 执行函数);
/// 
/// async fn 执行函数(信令路由:信令路由,id:信令ID,单个信令:信令表)->anyhow_Result<信令表>{  }
/// 
/// ```
#[macro_export]
macro_rules! impl信令特征{
    ($struct_name:ident, $async_func:expr) => {
        impl 信令特征 for $struct_name {
            // #[inline]
            // fn into_BoxAny(self:Box<Self>) -> Box<dyn Any> {  self  }
            // fn as_Any(&mut self) -> &mut dyn std::any::Any{  self  }
            // fn 信令名(&self)->String{ format!("{:?}",self) }
            // #[inline]
            // fn clone_Box(&self) -> Box信令特征 {  Box::new(self.clone())  }
            // #[inline]
            // fn into_Box(self) -> Box信令特征{ Box::new(self)  }     // Box::new(结果) as Box信令特征

            fn 动态执行函数Box(self:Box<Self>, 信令路由:信令路由, id:信令ID)-> 信令异步执行函数{   
                Box::pin(async move{
                    let 返回信令 = $async_func(信令路由, id, *self).await?;
                    Ok(Box::new(返回信令) as Box信令特征)
                })
            }
            fn 动态执行函数(self, 信令路由:信令路由,id:信令ID)->信令异步执行函数{
                Box::pin(async move{
                    let 返回信令 = $async_func(信令路由, id, self).await?;
                    Ok(Box::new(返回信令) as Box信令特征)
                })
            }
        }
        #[allow(dead_code)]
        impl $struct_name {
            
            fn 发布信令任务<F,T>(self,信令路由obj:信令路由, 解析信令函数:F ) -> impl 信令任务<T>
                where F: FnOnce(anyhow_Result<Self>) -> anyhow_Result<T> 
            {
                信令任务Builder::new(|本地运行bool| async move{
                    解析信令函数(
                        if 本地运行bool || 信令路由obj.inner判断无服务端(){
                            Box::pin($async_func(信令路由obj, 0, self)).await    /*在此处 解包执行*/
                        }else{
                            信令路由obj.task发布信令_异步(self).await?.try_into()  /*在服务端 解包执行*/
                        }
                    )
                })
            }
        }


        // <Box信令特征>.try_into()  或   <$struct_name>::try_from(Box信令特征)
        impl TryFrom<Box信令特征> for $struct_name {
            type Error = anyhow_Error;
            fn try_from(item: Box信令特征) -> Result<Self, Self::Error> {
                // (item as Box<dyn Any>).downcast::< Self >().map(|value|*value).map_err(|err|anyhow_err!("【Box信令特征try_from  错误】 => {err:?}"))
                match (item as Box<dyn Any>).downcast::< Self >(){
                    Ok(val)=>{ Ok(*val) }
                    Err(err)=>{ Err(anyhow_err!("【Box信令特征try_from  错误】 => {err:?}")) }
                }
            }
        }

        /*
        // <$struct_name> .to_string()
        impl std::fmt::Display for $struct_name {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                match serde_json::to_string(self){
                    Ok(string)=>{ write!(f, "{}", string)  }
                    Err(_)=>{ Err(std::fmt::Error) }
                }
            }
        }
        // <String>.try_into()   或   <$struct_name>::try_from(String)
        impl TryFrom<String> for $struct_name {
            type Error = anyhow_Error;
            fn try_from(item: String) -> Result<Self, Self::Error> {
                Ok(from_str::< Self >(item.as_ref())?)
            }
        }
        // <&str>.try_into()   或   <$struct_name>::try_from(&str)
        impl TryFrom<&str> for $struct_name {
            type Error = anyhow_Error;
            fn try_from(item: &str) -> Result<Self, Self::Error> {
                Ok(from_str::< Self >(item)?)
            }
        }
        */
    };
}





 

/// ## 从 枚举enum 取出值
/// ```no_run
/// enum aenum {
///     abc,
///     bcd{ one:String, two:u16  },
///     efg(u128, String),
/// }
/// let a = aenum::abc;
/// let b = aenum::bcd{ one: "nihao".to_string(), two: 12 };
/// let c = aenum::efg( 99, "book".to_string() );
/// 
/// match取出!(a, aenum::abc )                   // -->  ()
/// match取出!(a, aenum::bcd => one )            // -->  "nihao"
/// match取出!(a, aenum::bcd => one, two )       // -->  ("nihao", 12)
/// match取出!(a, aenum::efg => <u128> )         // -->  99
/// match取出!(a, aenum::efg => <u128, String> ) // -->  (99, "book")
/// ```
#[macro_export]
macro_rules! match取出{
    // aenum::abc
    ($变量:expr, $enum_路径:path ) => {
        match $变量 {
            $enum_路径 => Ok(()),
            _ => Err(anyhow_err!("match取出!() 错误匹配  {}", stringify!($enum_路径))),
        }
    };
    // aenum::bcd{ one: "nihao".to_string(), two: 12 }
    ($变量:expr, $enum_路径:path => $($field:ident),+  ) => {
        match $变量 {
            $enum_路径 { $($field),+, .. } => Ok(  ($($field),+)  ),
            _ => Err(anyhow_err!("match取出!() 错误匹配  {}", stringify!($enum_路径))),
        }
    };
    // aenum::efg(99, "book".to_string())
    ($变量:expr, $enum_路径:path => <$($type_index:tt),+> ) => {
        match $变量 {
            $enum_路径 ($($type_index),+) => Ok(  ($($type_index),+)  ),
            _ => Err(anyhow_err!("match取出!() 错误匹配  {}", stringify!($enum_路径))),
        }
    };
}




#[cfg(test)]
mod  测试{
    use crate::prelude::*;
    
    #[test]
    fn test_match取出()->anyhow_Result<()>{
           enum aenum {
                abc,
                bcd{ one:String, two:u16  },
                efg(u128, String),
           }
        //    let all = aenum::efg(99, "book".to_string());
        //    match all {
        //       aenum::abc =>{ }
        //       aenum::bcd{one, two }=>{ }
        //       aenum::efg(num,str) =>{ }
        //    }
           
           let a = aenum::abc;
           let b = aenum::bcd{ one: "nihao".to_string(), two: 12 };
           let c = aenum::efg( 99, "book".to_string() );
           let res_a = match取出!(a, aenum::abc )?;
           let res_b= match取出!(b, aenum::bcd => one, two )?;
           let res_c = match取出!(c, aenum::efg => <u128, String> )?;
           
           println!("test_match取出: {res_a:?}  {res_b:?}  {res_c:?}");
           Ok(())
     }
}




#[macro_export] 
macro_rules! cfg_多行特性 {
    (
        #![$meta:meta]
        $($item:item)*
    ) => {
        $(
            #[cfg($meta)]
            // #[cfg_attr(docsrs, doc(cfg($meta)))]
            $item
        )*
    }
}



/// - 来自开源仓库 cfg-if
/// - <https://docs.rs/cfg-if/latest/src/cfg_if/lib.rs.html>
#[macro_export]
macro_rules! cfg_if {
    // match if/else chains with a final `else`
    (
        $(
            if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
        ) else+
        else { $( $e_tokens:tt )* }
    ) => {
        $crate::cfg_if! {
            @__items () ;
            $(
                (( $i_meta ) ( $( $i_tokens )* )) ,
            )+
            (() ( $( $e_tokens )* )) ,
        }
    };

    // match if/else chains lacking a final `else`
    (
        if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
        $(
            else if #[cfg( $e_meta:meta )] { $( $e_tokens:tt )* }
        )*
    ) => {
        $crate::cfg_if! {
            @__items () ;
            (( $i_meta ) ( $( $i_tokens )* )) ,
            $(
                (( $e_meta ) ( $( $e_tokens )* )) ,
            )*
        }
    };

    // Internal and recursive macro to emit all the items
    //
    // Collects all the previous cfgs in a list at the beginning, so they can be
    // negated. After the semicolon are all the remaining items.
    (@__items ( $( $_:meta , )* ) ; ) => {};
    (
        @__items ( $( $no:meta , )* ) ;
        (( $( $yes:meta )? ) ( $( $tokens:tt )* )) ,
        $( $rest:tt , )*
    ) => {
        // Emit all items within one block, applying an appropriate #[cfg]. The
        // #[cfg] will require all `$yes` matchers specified and must also negate
        // all previous matchers.
        #[cfg(all(
            $( $yes , )?
            not(any( $( $no ),* ))
        ))]
        $crate::cfg_if! { @__identity $( $tokens )* }

        // Recurse to emit all other items in `$rest`, and when we do so add all
        // our `$yes` matchers to the list of `$no` matchers as future emissions
        // will have to negate everything we just matched as well.
        $crate::cfg_if! {
            @__items ( $( $no , )* $( $yes , )? ) ;
            $( $rest , )*
        }
    };

    // Internal macro to make __apply work out right for different match types,
    // because of how macros match/expand stuff.
    (@__identity $( $tokens:tt )* ) => {
        $( $tokens )*
    };
}




/// - std::path::PathBuf   .push()
#[macro_export]
macro_rules! join_path {
    ($($part:expr),+) => {
        {
            let mut p = std::path::PathBuf::new();
            $(
                p.push($part);
            )*
            p.display().to_string()
        }
    }
}




/*

macro_rules! 字面量_literal {      //整数、浮点数、字符串、布尔值等。
    ($l:literal) => {
        eprintln!("字面量 {} 的类型是: {}", $l, std::any::type_name::<_>($l));
    };
}
macro_rules! 表达式_expr {         //比如函数调用、算术运算、变量引用等。
    ($e:expr) => {
        eprintln!("表达式 {} 的值是: {}", stringify!($e), $e);
    };
}
macro_rules! 标识符declare_variable {  //标识符可以是变量名、函数名、结构体名等
    ($name:ident, $value:expr) => {
        let $name = $value;
        eprintln!("变量 {} 的值是: {}", stringify!($name), $name);
    };
}




#[macro_export]   // 输出的类型标注  Box<dyn Fn(信令路由, u64, 信令表) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> + Send + 'static> 
macro_rules! 信令路由_注册执行函数{
    ($exec_map:ident, $func_name:literal, $func:expr) => {
        $exec_map.insert(
            $func_name.to_string(),
            Box::new(move |信令路由: 信令路由, id: u64, 单个信令: 信令表|{
                Box::pin(async move {  $func(信令路由, id, 单个信令).await;  })
            }),
        );
    }
}

#[macro_export] 
macro_rules! 取出Arc内部值{
    ($arc_value:expr) =>{
        if Arc::strong_count(&$arc_value) <= 1 {  Arc::try_unwrap($arc_value).unwrap()   }else{   (*$arc_value).clone()   }
    }
}


*/