1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
/// Constructs a pathlike type for `AT`, `DetachedPath`, and `CpsBatch`. /// /// The invocation `path!(I1, I2, .. In)` resolves into /// `(..(((), I1), I2) .. In)`. /// /// ### Usage example /// /// ``` /// # use smart_access::{ AT, Cps, path }; /// type AccessIJ<CPS> = AT<CPS, path!(usize, usize)>; /// /// let mut foo = vec![vec![1,2], vec![3,4]]; /// let path: AccessIJ<_> = foo.at(0).at(1); /// /// # #[cfg(feature="batch_ct")] fn some_fn() { /// # use smart_access::{ CpsBatch }; /// type Batch2<CPS,F,G> = CpsBatch<CPS, path!(F, G)>; /// let mut bar = 42; /// let batch: Batch2<_,_,_> = bar.batch_ct().add(|x,_| *x + 1).add(|x,_| 2 * *x); /// # } /// /// # #[cfg(feature="detach")] fn some_fn2() { /// # use smart_access::{ DetachedPath, detached_at }; /// type DetachedIJ<T> = DetachedPath<Vec<Vec<T>>, path!(usize, usize)>; /// /// let detached_path: DetachedIJ<f64> = detached_at(4).at(2); /// # } /// ``` #[macro_export] macro_rules! path { // first, we reverse the path due to limitations in the macro matcher // (we can't use ($($tt:ty,)* $t:ty) because of an ambiguity) ( $($tt:ty),* ) => { $crate::path!( $($tt),* ;; ) }; ( $t:ty $(,$tt:ty)* ;; $($rev:ty),* ) => { $crate::path!( $($tt),* ;; $t $(,$rev)* ) }; // now we construct the reversed-reversed path type ( ;; $t:ty $(,$tt:ty)* ) => { ($crate::path!(;; $($tt),* ), $t) }; ( ;; ) => { () }; }