satex-core 0.2.1

Satex核心库,提供基础和通用的一些功能。
Documentation
#[macro_export]
macro_rules! export_make {
    ($name:ident) => {
        $crate::concat_idents!(make_registry=$name, Registry {
            pub use registry::make_registry;
        });
        $crate::concat_idents!(arc_make=Arc, $name {
            pub use make::{arc_make, $name};
        });
    };
}

#[macro_export]
macro_rules! make {
    (@compcat,$make_name:ident, $make_out_name:ident, ($($make_out_type:tt)+), $arc_make_out_type:ty) =>{
        make!(@compcat, $make_name, $make_out_name, ($($make_out_type)+), ($crate::config::args::Args), $arc_make_out_type);
    };

    (@compcat,$make_name:ident, $make_out_name:ident, ($($make_out_type:tt)+), ($($args_type:tt)+), $arc_make_out_type:ty) => {

        pub trait $make_name {
            type $make_out_name: $($make_out_type)+;

            fn name(&self) -> &'static str;

            fn make(&self, args: $($args_type)+) -> Result<Self::$make_out_name, $crate::Error>;
        }

        struct MakeFn<M, F> {
            make: M,
            f: F,
        }

        impl<M, F> MakeFn<M, F> {
            pub fn new(make: M, f: F) -> Self {
                Self { make, f }
            }
        }

        impl<M, F, T> $make_name for MakeFn<M, F>
        where
            M: $make_name,
            F: Fn(M::$make_out_name) -> T,
            T: $($make_out_type)+,
        {
            type $make_out_name = T;

            fn name(&self) -> &'static str {
                self.make.name()
            }

            fn make(&self, args: $($args_type)+) -> Result<Self::$make_out_name,$crate::Error> {
                self.make.make(args).map(|out| (self.f)(out))
            }
        }

        $crate::concat_idents!(arc_make = Arc, $make_name {

            #[derive(Clone)]
            pub struct arc_make(
                std::sync::Arc<
                    dyn $make_name<$make_out_name = $arc_make_out_type> + Send + Sync + 'static,
                >,
            );

            impl $make_name for arc_make {
                type $make_out_name = $arc_make_out_type;

                fn name(&self) -> &'static str {
                    self.0.name()
                }

                fn make(&self, args: $($args_type)+) -> Result<Self::$make_out_name, $crate::Error> {
                    self.0.make(args)
                }
            }
        });
    };

    ($make_name:ident, $make_out_name:ident, ($($make_out_type:tt)+), $arc_make_out_type:ty) => {
        make!($make_name, $make_out_name, ($($make_out_type)+), ($crate::config::args::Args), $arc_make_out_type);
    };

    ($make_name:ident, $make_out_name:ident, ($($make_out_type:tt)+), ($($args_type:tt)+), $arc_make_out_type:ty) => {

        make!(@compcat, $make_name, $make_out_name, ($($make_out_type)+), ($($args_type)+), $arc_make_out_type);

        $crate::concat_idents!(arc_make = Arc, $make_name {
            impl arc_make {
                pub fn new<M, O>(make: M) -> Self
                    where
                        M: $make_name<$make_out_name = O> + Send + Sync + 'static,
                        O: $($make_out_type)+ + Send + Sync + 'static,
                    {
                        let name = make.name();
                        Self(std::sync::Arc::new(MakeFn::new(
                            make,
                            |inner| <$arc_make_out_type>::new(name,inner),
                        )))
                    }
            }
        });
    };
}

#[macro_export]
macro_rules! make_impl {
    (@internal $make_trait:ident,$classify:ident,$name:ident) => {
        $crate::concat_idents!(make_classify=Make,$name,$classify{
             #[derive(Default, Debug, Clone, Copy)]
             pub struct make_classify;

             impl $make_trait for make_classify {
                type $classify = __Classify;

                fn name(&self) -> &'static str {
                    stringify!($name)
                }

                fn make(&self, args: Args) -> Result<Self::$classify, Error> {
                    make(args)
                }
            }
         });
    };
    ($make_trait:ident,$classify:ident,$name:ident) => {
        $crate::concat_idents!(classify = $name,$classify {
            type __Classify = classify;
        });
        $crate::make_impl!(@internal $make_trait,$classify,$name);
    };
    ($make_trait:ident,$classify:ident,$name:ident,$mode:ident,$($(#[$meta:meta])* $vis:vis $field:ident:$ty:ty),* $(,)?) => {
        $crate::concat_idents!(classify = $name,$classify {
            type __Classify = classify;
            $crate::config!($name,$mode,$($(#[$meta])* $vis $field : $ty),*);
        });
        $crate::make_impl!(@internal $make_trait,$classify,$name);
    };
}