From 450429a52932511243399dd51d370c0872d5f0a1 Mon Sep 17 00:00:00 2001 From: Nugine Date: Sun, 26 Jan 2025 19:47:15 +0800 Subject: [PATCH] feat: add chain! --- const-str/src/__ctfe/chain.rs | 53 +++++++++++++++++++++++++++++++++++ const-str/src/lib.rs | 3 ++ 2 files changed, 56 insertions(+) create mode 100644 const-str/src/__ctfe/chain.rs diff --git a/const-str/src/__ctfe/chain.rs b/const-str/src/__ctfe/chain.rs new file mode 100644 index 0000000..0b2b20c --- /dev/null +++ b/const-str/src/__ctfe/chain.rs @@ -0,0 +1,53 @@ +/// Chains multiple macro calls together. +/// +/// `_` is used as a placeholder for the value that is being passed through the chained calls. +/// +/// # Examples +/// +/// ``` +/// use const_str::{chain, concat, replace, split}; +/// +/// const TOP: &str = "std"; +/// +/// const PARTS: &[&str] = &chain! { +/// stringify!(std::sync::atomic::Ordering::Relaxed), +/// replace!(_, { concat!(TOP, "::") }, ""), +/// split!(_, "::"), +/// }; +/// +/// assert_eq!(PARTS, &["sync", "atomic", "Ordering", "Relaxed"]); +/// ``` +#[macro_export] +macro_rules! chain { + ($init:expr, $( $call:ident!($($arg:tt),+), )+) => { + $crate::__chain_impl!(@chain $init, $( $call!($($arg),+) ),+) + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! __chain_impl { + (@chain $init:expr, $call:ident!($($arg:tt),+)) => { + $crate::__chain_impl!(@call $init, $call!($($arg),+)) + }; + + (@chain $init:expr, $call:ident!($($arg:tt),+), $($rest:tt)+) => { + $crate::__chain_impl!(@chain $crate::__chain_impl!(@call $init, $call!($($arg),+)), $($rest)+) + }; + + (@call $e: expr, $call:ident!($($arg:tt),+)) => { + $call!( + $( + $crate::__chain_impl!(@replace $e, $arg) + ),+ + ) + }; + + (@replace $e:expr, _) => { + $e + }; + + (@replace $e:expr, $tt:tt) => { + $tt + }; +} diff --git a/const-str/src/lib.rs b/const-str/src/lib.rs index 0b61f8c..955c038 100644 --- a/const-str/src/lib.rs +++ b/const-str/src/lib.rs @@ -66,6 +66,9 @@ pub mod __ctfe { mod ascii_case; pub use self::ascii_case::*; + mod chain; + // pub use self::chain::*; + mod compare; pub use self::compare::*;