Skip to main content

variadics/
lib.rs

1#![warn(missing_docs)]
2#![doc = include_str!("../README.md")]
3//!  
4//!
5//! # Main Macros
6//!
7//! ## [`var_expr!`]
8#![doc = include_str!("../var_expr.md")]
9//! ## [`var_type!`]
10#![doc = include_str!("../var_type.md")]
11//! ## [`var_args!`]
12#![doc = include_str!("../var_args.md")]
13#![cfg_attr(docsrs, feature(doc_cfg))]
14#![cfg_attr(not(any(test, feature = "std")), no_std)]
15
16extern crate alloc;
17
18use core::any::Any;
19
20use sealed::sealed;
21/// module of collection types for variadics
22#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
23#[cfg(feature = "std")]
24pub mod variadic_collections;
25
26#[doc = include_str!("../var_expr.md")]
27#[macro_export]
28macro_rules! var_expr {
29    () => ( () );
30
31    (...$a:ident $(,)? ) => ( $a );
32    (...$a:expr  $(,)? ) => ( $a );
33    (...$a:ident, $( $b:tt )+) => ( $crate::VariadicExt::extend($a, $crate::var_expr!( $( $b )* )) );
34    (...$a:expr,  $( $b:tt )+) => ( $crate::VariadicExt::extend($a, $crate::var_expr!( $( $b )* )) );
35
36    ($a:ident $(,)? ) => ( ($a, ()) );
37    ($a:expr  $(,)? ) => ( ($a, ()) );
38    ($a:ident, $( $b:tt )+) => ( ($a, $crate::var_expr!( $( $b )* )) );
39    ($a:expr,  $( $b:tt )+) => ( ($a, $crate::var_expr!( $( $b )* )) );
40}
41
42#[doc = include_str!("../var_type.md")]
43#[macro_export]
44macro_rules! var_type {
45    () => ( () );
46
47    (...$a:ty $(,)? ) => ( $a );
48    (...$a:ty, $( $b:tt )+) => ( <$a as $crate::VariadicExt>::Extend::<$crate::var_type!( $( $b )* )> );
49
50    ($a:ty $(,)? ) => ( ($a, ()) );
51    ($a:ty, $( $b:tt )+) => ( ($a, $crate::var_type!( $( $b )* )) );
52}
53
54#[doc = include_str!("../var_args.md")]
55#[macro_export]
56macro_rules! var_args {
57    () => ( () );
58
59    (...$a:pat $(,)? ) => ( $a );
60    (...$a:ty, $( $b:tt )+) => ( ::core::compile_error!("`var_args!` can only have the `...` spread syntax on the last field.") );
61
62    ($a:pat $(,)? ) => ( ($a, ()) );
63    ($a:pat, $( $b:tt )+) => ( ($a, $crate::var_args!( $( $b )* )) );
64}
65
66/// This macro generates a basic variadic trait where each element must fulfill the `where` clause.
67///
68/// ```rust
69/// use variadics::{var_expr, variadic_trait};
70///
71/// variadic_trait! {
72///     /// A variadic list of `Debug` items.
73///     pub variadic<Item> DebugList where Item: core::fmt::Debug {}
74/// }
75///
76/// let x = &var_expr!(1, "hello", 5.6);
77/// let _: &dyn DebugList = x;
78/// println!("{:?}", x);
79/// ```
80///
81/// This uses a special syntax similar to traits, but with the `trait` keyword replaced with
82/// `variadic<T>` where `T` is the generic parameter name for each item in the variadic list. `T`
83/// can be changed to any valid generic identifier. The bounds on `T` must be put in the where
84/// clause; they cannot be expressed directly-- `variadic<T: Clone>` is invalid.
85///
86/// For now this can only create traits which bounds the `Item`s and cannot have associated
87/// methods. This means the body of the variadic trait must be empty. But in the future this
88/// declarative macro may be converted into a more powerful procedural macro with associated
89/// method support.
90#[macro_export]
91macro_rules! variadic_trait {
92    (
93        $( #[$( $attrs:tt )*] )*
94        $vis:vis variadic<$item:ident> $name:ident $( $clause:tt )*
95    ) => {
96        $( #[$( $attrs )*] )*
97        $vis trait $name: $crate::Variadic {}
98        $( #[$( $attrs )*] )*
99        impl $name for $crate::var_type!() {}
100        $( #[$( $attrs )*] )*
101        impl<$item, __Rest: $name> $name for $crate::var_type!($item, ...__Rest) $( $clause )*
102    };
103}
104
105/// A variadic tuple list.
106///
107/// This is a sealed trait, implemented only for `(Item, Rest) where Rest: Variadic` and `()`.
108#[sealed]
109pub trait Variadic {}
110#[sealed]
111impl<Item, Rest> Variadic for (Item, Rest) where Rest: Variadic {}
112#[sealed]
113impl Variadic for () {}
114
115/// Extension methods/types for [`Variadic`]s.
116///
117/// This is a sealed trait.
118#[sealed]
119pub trait VariadicExt: Variadic {
120    /// The number of items in this variadic (its length).
121    const LEN: usize;
122
123    /// Creates a new (longer) variadic type by appending `Suffix` onto the end of this variadc.
124    type Extend<Suffix>: VariadicExt
125    where
126        Suffix: VariadicExt;
127    /// Extends this variadic value by appending `suffix` onto the end.
128    fn extend<Suffix>(self, suffix: Suffix) -> Self::Extend<Suffix>
129    where
130        Suffix: VariadicExt;
131
132    /// The reverse of this variadic type.
133    type Reverse: VariadicExt;
134    /// Reverses this variadic value.
135    fn reverse(self) -> Self::Reverse;
136    /// Reverses an AsRefVar variadic value
137    fn reverse_ref(this: Self::AsRefVar<'_>) -> <Self::Reverse as VariadicExt>::AsRefVar<'_>;
138
139    /// The length of this variadic type
140    fn len(&self) -> usize {
141        Self::LEN
142    }
143
144    /// Checks if this variadic type is empty.
145    fn is_empty(&self) -> bool {
146        Self::LEN == 0
147    }
148
149    /// This as a variadic of references.
150    type AsRefVar<'a>: RefVariadic<UnRefVar = Self, RefVar = Self::AsRefVar<'a>, MutVar = Self::AsMutVar<'a>>
151    where
152        Self: 'a;
153    /// Convert a reference to this variadic into a variadic of references.
154    /// ```rust
155    /// # use variadics::*;
156    /// let as_ref: var_type!(&u32, &String, &bool) =
157    ///     var_expr!(1_u32, "Hello".to_owned(), false).as_ref_var();
158    /// ```
159    fn as_ref_var(&self) -> Self::AsRefVar<'_>;
160
161    /// This as a variadic of exclusive (`mut`) references.
162    type AsMutVar<'a>: MutVariadic<UnRefVar = Self, RefVar = Self::AsRefVar<'a>, MutVar = Self::AsMutVar<'a>>
163    where
164        Self: 'a;
165    /// Convert an exclusive (`mut`) reference to this variadic into a variadic of exclusive
166    /// (`mut`) references.
167    /// ```rust
168    /// # use variadics::*;
169    /// let as_mut: var_type!(&mut u32, &mut String, &mut bool) =
170    ///     var_expr!(1_u32, "Hello".to_owned(), false).as_mut_var();
171    /// ```
172    fn as_mut_var(&mut self) -> Self::AsMutVar<'_>;
173
174    /// Iterator type returned by [`Self::iter_any_ref`].
175    type IterAnyRef<'a>: Iterator<Item = &'a dyn Any>
176    where
177        Self: 'static;
178    /// Iterate this variadic as `&dyn Any` references.
179    fn iter_any_ref(&self) -> Self::IterAnyRef<'_>
180    where
181        Self: 'static;
182
183    /// Iterator type returned by [`Self::iter_any_mut`].
184    type IterAnyMut<'a>: Iterator<Item = &'a mut dyn Any>
185    where
186        Self: 'static;
187    /// Iterate this variadic as `&mut dyn Any` exclusive references.
188    fn iter_any_mut(&mut self) -> Self::IterAnyMut<'_>
189    where
190        Self: 'static;
191
192    /// type for all elements of the variadic being wrapped in `Option`
193    type IntoOption;
194    /// wrap all elements of the variadic in `Option``
195    fn into_option(self) -> Self::IntoOption;
196
197    /// type for all elements of the variadic being wrapped in `Vec`
198    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
199    #[cfg(feature = "std")]
200    type IntoVec: VecVariadic<UnVec = Self> + Default;
201    /// wrap all elements of the variadic in a `Vec`
202    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
203    #[cfg(feature = "std")]
204    fn into_singleton_vec(self) -> Self::IntoVec;
205}
206
207#[sealed]
208impl<Item, Rest> VariadicExt for (Item, Rest)
209where
210    Rest: VariadicExt,
211{
212    const LEN: usize = 1 + Rest::LEN;
213
214    type Extend<Suffix>
215        = (Item, Rest::Extend<Suffix>)
216    where
217        Suffix: VariadicExt;
218    fn extend<Suffix>(self, suffix: Suffix) -> Self::Extend<Suffix>
219    where
220        Suffix: VariadicExt,
221    {
222        let (item, rest) = self;
223        (item, rest.extend(suffix))
224    }
225
226    type Reverse = <Rest::Reverse as VariadicExt>::Extend<(Item, ())>;
227    fn reverse(self) -> Self::Reverse {
228        let (item, rest) = self;
229        rest.reverse().extend((item, ()))
230    }
231    fn reverse_ref(this: Self::AsRefVar<'_>) -> <Self::Reverse as VariadicExt>::AsRefVar<'_> {
232        let (item, rest) = this;
233        let out = Rest::reverse_ref(rest).extend((item, ()));
234        // TODO(mingwei): check if use of unsafe is necessary
235        let out2 = unsafe { core::mem::transmute_copy(&out) };
236        core::mem::forget(out);
237        out2
238    }
239
240    type AsRefVar<'a>
241        = (&'a Item, Rest::AsRefVar<'a>)
242    where
243        Self: 'a;
244    fn as_ref_var(&self) -> Self::AsRefVar<'_> {
245        let (item, rest) = self;
246        (item, rest.as_ref_var())
247    }
248
249    type AsMutVar<'a>
250        = (&'a mut Item, Rest::AsMutVar<'a>)
251    where
252        Self: 'a;
253    fn as_mut_var(&mut self) -> Self::AsMutVar<'_> {
254        let (item, rest) = self;
255        (item, rest.as_mut_var())
256    }
257
258    type IterAnyRef<'a>
259        = core::iter::Chain<core::iter::Once<&'a dyn Any>, Rest::IterAnyRef<'a>>
260    where
261        Self: 'static;
262    fn iter_any_ref(&self) -> Self::IterAnyRef<'_>
263    where
264        Self: 'static,
265    {
266        let var_args!(item, ...rest) = self;
267        let item: &dyn Any = item;
268        core::iter::once(item).chain(rest.iter_any_ref())
269    }
270
271    type IterAnyMut<'a>
272        = core::iter::Chain<core::iter::Once<&'a mut dyn Any>, Rest::IterAnyMut<'a>>
273    where
274        Self: 'static;
275    fn iter_any_mut(&mut self) -> Self::IterAnyMut<'_>
276    where
277        Self: 'static,
278    {
279        let var_args!(item, ...rest) = self;
280        let item: &mut dyn Any = item;
281        core::iter::once(item).chain(rest.iter_any_mut())
282    }
283
284    type IntoOption = (Option<Item>, Rest::IntoOption);
285    fn into_option(self) -> Self::IntoOption {
286        let var_args!(item, ...rest) = self;
287        var_expr!(Some(item), ...rest.into_option())
288    }
289
290    #[cfg(feature = "std")]
291    type IntoVec = (Vec<Item>, Rest::IntoVec);
292    #[cfg(feature = "std")]
293    fn into_singleton_vec(self) -> Self::IntoVec {
294        let var_args!(item, ...rest) = self;
295        var_expr!(vec!(item), ...rest.into_singleton_vec())
296    }
297}
298
299#[sealed]
300impl VariadicExt for () {
301    const LEN: usize = 0;
302
303    type Extend<Suffix>
304        = Suffix
305    where
306        Suffix: VariadicExt;
307    fn extend<Suffix>(self, suffix: Suffix) -> Self::Extend<Suffix>
308    where
309        Suffix: VariadicExt,
310    {
311        suffix
312    }
313
314    type Reverse = ();
315    fn reverse(self) -> Self::Reverse {}
316    fn reverse_ref(_this: Self::AsRefVar<'_>) -> <Self::Reverse as VariadicExt>::AsRefVar<'_> {}
317
318    type AsRefVar<'a> = ();
319    fn as_ref_var(&self) -> Self::AsRefVar<'_> {}
320
321    type AsMutVar<'a> = ();
322    fn as_mut_var(&mut self) -> Self::AsMutVar<'_> {}
323
324    type IterAnyRef<'a>
325        = core::iter::Empty<&'a dyn Any>
326    where
327        Self: 'static;
328    fn iter_any_ref(&self) -> Self::IterAnyRef<'_>
329    where
330        Self: 'static,
331    {
332        core::iter::empty()
333    }
334
335    type IterAnyMut<'a>
336        = core::iter::Empty<&'a mut dyn Any>
337    where
338        Self: 'static;
339    fn iter_any_mut(&mut self) -> Self::IterAnyMut<'_>
340    where
341        Self: 'static,
342    {
343        core::iter::empty()
344    }
345
346    type IntoOption = ();
347    fn into_option(self) -> Self::IntoOption {}
348
349    #[cfg(feature = "std")]
350    type IntoVec = ();
351    #[cfg(feature = "std")]
352    fn into_singleton_vec(self) -> Self::IntoVec {}
353}
354
355/// A variadic of either shared references, exclusive references, or both.
356///
357/// Provides the [`Self::UnRefVar`] associated type which is the original variadic of owned values.
358///
359/// This is a sealed trait.
360#[sealed]
361pub trait EitherRefVariadic: VariadicExt {
362    /// The un-referenced variadic. Each item will have one layer of shared references removed.
363    ///
364    /// The inverse of [`VariadicExt::AsRefVar`] and [`VariadicExt::AsMutVar`].
365    ///
366    /// ```rust
367    /// # use variadics::*;
368    /// let un_ref: <var_type!(&u32, &String, &bool) as EitherRefVariadic>::UnRefVar =
369    ///     var_expr!(1_u32, "Hello".to_owned(), false);
370    /// ```
371    type UnRefVar: VariadicExt;
372
373    /// This type with all exclusive `&mut` references replaced with shared `&` references.
374    ///
375    /// Returned by [`Self::mut_to_ref`].
376    type RefVar: RefVariadic<UnRefVar = Self::UnRefVar, RefVar = Self::RefVar>;
377    /// Convert all exclusive (`mut`) references into shared references: [`RefVariadic`].
378    ///
379    /// ```rust
380    /// # use variadics::*;
381    /// let mut original = var_expr!(1_u32, "Hello".to_owned(), false);
382    /// let as_mut: var_type!(&mut u32, &mut String, &mut bool) = original.as_mut_var();
383    /// let as_ref_1: var_type!(&u32, &String, &bool) = as_mut.mut_to_ref();
384    /// let as_ref_2: var_type!(&u32, &String, &bool) = as_ref_1; // Can copy the reference version.
385    /// drop((as_ref_1, as_ref_2));
386    /// ```
387    fn mut_to_ref(self) -> Self::RefVar;
388
389    /// This type with all shared `&` references replaced with exclusive references `&mut`.
390    ///
391    /// Conversion from `&` to `&mut` is generally invalid, so a `ref_to_mut()` method does not exist.
392    type MutVar: MutVariadic<UnRefVar = Self::UnRefVar, MutVar = Self::MutVar>;
393
394    /// convert entries to [`<UnRefVar as VariadicExt>::AsRefVar`](VariadicExt::AsRefVar)
395    fn unref_ref(&self) -> <Self::UnRefVar as VariadicExt>::AsRefVar<'_>;
396}
397#[sealed]
398impl<'a, Item, Rest> EitherRefVariadic for (&'a Item, Rest)
399where
400    Rest: EitherRefVariadic,
401{
402    type UnRefVar = (Item, Rest::UnRefVar);
403
404    type RefVar = (&'a Item, Rest::RefVar);
405    fn mut_to_ref(self) -> Self::RefVar {
406        let var_args!(item, ...rest) = self;
407        var_expr!(item, ...rest.mut_to_ref())
408    }
409
410    type MutVar = (&'a mut Item, Rest::MutVar);
411
412    fn unref_ref(&self) -> <Self::UnRefVar as VariadicExt>::AsRefVar<'_> {
413        let var_args!(item, ...rest) = self;
414        var_expr!(item, ...rest.unref_ref())
415    }
416}
417#[sealed]
418impl<'a, Item, Rest> EitherRefVariadic for (&'a mut Item, Rest)
419where
420    Rest: EitherRefVariadic,
421{
422    type UnRefVar = (Item, Rest::UnRefVar);
423
424    type RefVar = (&'a Item, Rest::RefVar);
425    fn mut_to_ref(self) -> Self::RefVar {
426        let var_args!(item, ...rest) = self;
427        var_expr!(&*item, ...rest.mut_to_ref())
428    }
429
430    type MutVar = (&'a mut Item, Rest::MutVar);
431
432    fn unref_ref(&self) -> <Self::UnRefVar as VariadicExt>::AsRefVar<'_> {
433        let var_args!(item, ...rest) = self;
434        var_expr!(item, ...rest.unref_ref())
435    }
436}
437#[sealed]
438impl EitherRefVariadic for () {
439    type UnRefVar = ();
440
441    type RefVar = ();
442    fn mut_to_ref(self) -> Self::RefVar {}
443
444    type MutVar = ();
445
446    fn unref_ref(&self) -> <Self::UnRefVar as VariadicExt>::AsRefVar<'_> {}
447}
448
449/// A variadic where each item is a shared reference `&item`.
450///
451/// This can be created using [`VariadicExt::as_ref_var`]:
452/// ```rust
453/// # use variadics::*;
454/// let as_ref: var_type!(&u32, &String, &bool) =
455///     var_expr!(1_u32, "Hello".to_owned(), false).as_ref_var();
456/// ```
457///
458/// This is a sealed trait.
459#[sealed]
460pub trait RefVariadic: EitherRefVariadic<RefVar = Self>
461where
462    Self: Copy,
463{
464}
465#[sealed]
466impl<Item, Rest> RefVariadic for (&Item, Rest) where Rest: RefVariadic {}
467#[sealed]
468impl RefVariadic for () {}
469
470/// A variadic where each item is an exclusive reference `&mut item`.
471///
472/// This can be created using [`VariadicExt::as_mut_var`]:
473/// ```rust
474/// # use variadics::*;
475/// let as_mut: var_type!(&mut u32, &mut String, &mut bool) =
476///     var_expr!(1_u32, "Hello".to_owned(), false).as_mut_var();
477/// ```
478///
479/// This is a sealed trait.
480#[sealed]
481pub trait MutVariadic: EitherRefVariadic<MutVar = Self> {}
482#[sealed]
483impl<Item, Rest> MutVariadic for (&mut Item, Rest) where Rest: MutVariadic {}
484#[sealed]
485impl MutVariadic for () {}
486
487/// Copy a variadic of references [`EitherRefVariadic`] into a variadic of owned values [`EitherRefVariadic::UnRefVar`].
488///
489/// ```rust
490/// # use variadics::*;
491/// let ref_var = var_expr!(&1, &"hello", &false);
492/// let copy_var = ref_var.copy_var();
493/// assert_eq!(var_expr!(1, "hello", false), copy_var);
494/// ```
495#[sealed]
496pub trait CopyRefVariadic: EitherRefVariadic {
497    /// Copy self per-value.
498    fn copy_var(&self) -> Self::UnRefVar;
499}
500#[sealed]
501impl<Item, Rest> CopyRefVariadic for (&Item, Rest)
502where
503    Item: Copy,
504    Rest: CopyRefVariadic,
505{
506    fn copy_var(&self) -> Self::UnRefVar {
507        let &var_args!(&item, ...ref rest) = self;
508        var_expr!(item, ...rest.copy_var())
509    }
510}
511#[sealed]
512impl<Item, Rest> CopyRefVariadic for (&mut Item, Rest)
513where
514    Item: Copy,
515    Rest: CopyRefVariadic,
516{
517    fn copy_var(&self) -> Self::UnRefVar {
518        let &var_args!(&mut item, ...ref rest) = self;
519        var_expr!(item, ...rest.copy_var())
520    }
521}
522#[sealed]
523impl CopyRefVariadic for () {
524    fn copy_var(&self) -> Self::UnRefVar {}
525}
526
527/// Clone a variadic of references [`AsRefVar`](VariadicExt::AsRefVar) into a variadic of owned values.
528///
529/// ```rust
530/// # use variadics::*;
531/// let ref_var = var_expr!(&1, &format!("hello {}", "world"), &vec![1, 2, 3]);
532/// let clone_var = CloneVariadic::clone_ref_var(ref_var);
533/// assert_eq!(
534///     var_expr!(1, "hello world".to_owned(), vec![1, 2, 3]),
535///     clone_var
536/// );
537/// ```
538#[sealed]
539pub trait CloneVariadic: VariadicExt + Clone {
540    /// Clone a variadic of references [`AsRefVar`](VariadicExt::AsRefVar) into a variadic of owned values.
541    fn clone_ref_var(this: Self::AsRefVar<'_>) -> Self;
542}
543#[sealed]
544impl<Item, Rest> CloneVariadic for (Item, Rest)
545where
546    Item: Clone,
547    Rest: CloneVariadic,
548{
549    fn clone_ref_var(this: Self::AsRefVar<'_>) -> Self {
550        let var_args!(item, ...rest) = this;
551        var_expr!(item.clone(), ...Rest::clone_ref_var(rest))
552    }
553}
554#[sealed]
555impl CloneVariadic for () {
556    fn clone_ref_var(_this: Self::AsRefVar<'_>) -> Self {}
557}
558
559/// A variadic where all item implement [`PartialEq`].
560#[sealed]
561pub trait PartialEqVariadic: VariadicExt {
562    /// `PartialEq` between a referenced variadic and a variadic of references, of the same types.
563    fn eq(&self, other: &Self) -> bool;
564
565    /// `PartialEq` for the `AsRefVar` version op `Self`.
566    fn eq_ref(this: Self::AsRefVar<'_>, other: Self::AsRefVar<'_>) -> bool;
567}
568#[sealed]
569impl<Item, Rest> PartialEqVariadic for (Item, Rest)
570where
571    Item: PartialEq,
572    Rest: PartialEqVariadic,
573{
574    fn eq(&self, other: &Self) -> bool {
575        let var_args!(item_self, ...rest_self) = self;
576        let var_args!(item_other, ...rest_other) = other;
577        item_self == item_other && rest_self.eq(rest_other)
578    }
579
580    fn eq_ref(
581        this: <Self as VariadicExt>::AsRefVar<'_>,
582        other: <Self as VariadicExt>::AsRefVar<'_>,
583    ) -> bool {
584        let var_args!(item_self, ...rest_self) = this;
585        let var_args!(item_other, ...rest_other) = other;
586        item_self == item_other && Rest::eq_ref(rest_self, rest_other)
587    }
588}
589#[sealed]
590impl PartialEqVariadic for () {
591    fn eq(&self, _other: &Self) -> bool {
592        true
593    }
594
595    fn eq_ref(
596        _this: <Self as VariadicExt>::AsRefVar<'_>,
597        _other: <Self as VariadicExt>::AsRefVar<'_>,
598    ) -> bool {
599        true
600    }
601}
602
603/// A variadic where all elements are the same type, `T`.
604///
605/// This is a sealed trait.
606#[sealed]
607pub trait HomogenousVariadic<T>: Variadic {
608    /// Returns a reference to an element.
609    fn get(&self, i: usize) -> Option<&T>;
610    /// Returns an exclusive reference to an element.
611    fn get_mut(&mut self, i: usize) -> Option<&mut T>;
612
613    /// Iterator type returned by `into_iter`.
614    type IntoIter: Iterator<Item = T>;
615    /// Turns this `HomogenousVariadic<T>` into an iterator of items `T`.
616    fn into_iter(self) -> Self::IntoIter;
617}
618#[sealed]
619impl<T> HomogenousVariadic<T> for () {
620    fn get(&self, _i: usize) -> Option<&T> {
621        None
622    }
623    fn get_mut(&mut self, _i: usize) -> Option<&mut T> {
624        None
625    }
626
627    type IntoIter = core::iter::Empty<T>;
628    fn into_iter(self) -> Self::IntoIter {
629        core::iter::empty()
630    }
631}
632#[sealed]
633impl<T, Rest> HomogenousVariadic<T> for (T, Rest)
634where
635    Rest: HomogenousVariadic<T>,
636{
637    fn get(&self, i: usize) -> Option<&T> {
638        let (item, rest) = self;
639        if i == 0 { Some(item) } else { rest.get(i - 1) }
640    }
641    fn get_mut(&mut self, i: usize) -> Option<&mut T> {
642        let (item, rest) = self;
643        if i == 0 {
644            Some(item)
645        } else {
646            rest.get_mut(i - 1)
647        }
648    }
649
650    type IntoIter = core::iter::Chain<core::iter::Once<T>, Rest::IntoIter>;
651    fn into_iter(self) -> Self::IntoIter {
652        let (item, rest) = self;
653        core::iter::once(item).chain(rest.into_iter())
654    }
655}
656
657/// Helper trait for splitting a variadic into two parts. `Prefix` is the first part, everything
658/// after is the `Suffix` or second part.
659///
660/// This is a sealed trait.
661#[sealed]
662pub trait Split<Prefix>: VariadicExt
663where
664    Prefix: VariadicExt,
665{
666    /// The second part when splitting this variadic by `Prefix`.
667    type Suffix: VariadicExt;
668    /// Splits this variadic into two parts, first the `Prefix`, and second the `Suffix`.
669    fn split(self) -> (Prefix, Self::Suffix);
670    /// Splits a refvar variadic
671    fn split_ref(
672        this: Self::AsRefVar<'_>,
673    ) -> (
674        Prefix::AsRefVar<'_>,
675        <Self::Suffix as VariadicExt>::AsRefVar<'_>,
676    );
677}
678#[sealed]
679impl<Item, Rest, PrefixRest> Split<(Item, PrefixRest)> for (Item, Rest)
680where
681    PrefixRest: VariadicExt,
682    Rest: Split<PrefixRest>,
683{
684    /// The second part when splitting this variadic by `Prefix`.
685    type Suffix = <Rest as Split<PrefixRest>>::Suffix;
686    /// Splits this variadic into two parts, first the `Prefix`, and second the `Suffix`.
687    fn split(self) -> ((Item, PrefixRest), Self::Suffix) {
688        let (item, rest) = self;
689        let (prefix_rest, suffix) = rest.split();
690        ((item, prefix_rest), suffix)
691    }
692    /// Splits a refvar variadic
693    fn split_ref(
694        this: Self::AsRefVar<'_>,
695    ) -> (
696        <(Item, PrefixRest) as VariadicExt>::AsRefVar<'_>,
697        <Self::Suffix as VariadicExt>::AsRefVar<'_>,
698    ) {
699        let (item, rest) = this;
700        let (prefix_rest, suffix) = Rest::split_ref(rest);
701        ((item, prefix_rest), suffix)
702    }
703}
704#[sealed]
705impl<Rest> Split<var_type!()> for Rest
706where
707    Rest: VariadicExt,
708{
709    type Suffix = Rest;
710    fn split(self) -> (var_type!(), Self::Suffix) {
711        (var_expr!(), self)
712    }
713    fn split_ref(
714        this: Self::AsRefVar<'_>,
715    ) -> (var_type!(), <Self::Suffix as VariadicExt>::AsRefVar<'_>) {
716        (var_expr!(), this)
717    }
718}
719
720/// Helper trait for splitting a variadic into two parts. `Prefix` is the first part, everything
721/// after is the `Suffix` or second part.
722///
723/// This is a sealed trait.
724#[sealed]
725pub trait SplitBySuffix<Suffix>: VariadicExt
726where
727    Suffix: VariadicExt,
728{
729    /// The first part when splitting this variadic by `Suffix`.
730    type Prefix: VariadicExt;
731    /// Splits this variadic into two parts, first the `Prefix`, and second the `Suffix`.
732    fn split_by_suffix(self) -> (Self::Prefix, Suffix);
733    /// Splits a refvar variadic
734    fn split_by_suffix_ref(
735        this: Self::AsRefVar<'_>,
736    ) -> (
737        <Self::Prefix as VariadicExt>::AsRefVar<'_>,
738        Suffix::AsRefVar<'_>,
739    );
740}
741#[sealed]
742impl<Suffix, This> SplitBySuffix<Suffix> for This
743where
744    Suffix: VariadicExt,
745    This: VariadicExt,
746    This::Reverse: Split<Suffix::Reverse>,
747    Suffix::Reverse: VariadicExt<Reverse = Suffix>,
748{
749    /// The second part when splitting this variadic by `Prefix`.
750    type Prefix = <<This::Reverse as Split<Suffix::Reverse>>::Suffix as VariadicExt>::Reverse;
751    /// Splits this variadic into two parts, first the `Prefix`, and second the `Suffix`.
752    fn split_by_suffix(self) -> (Self::Prefix, Suffix) {
753        let (rsuffix, rprefix) = self.reverse().split();
754        (rprefix.reverse(), rsuffix.reverse())
755    }
756
757    fn split_by_suffix_ref(
758        this: Self::AsRefVar<'_>,
759    ) -> (
760        <Self::Prefix as VariadicExt>::AsRefVar<'_>,
761        Suffix::AsRefVar<'_>,
762    ) {
763        let rev = This::reverse_ref(this);
764        let (rsuffix, rprefix) = <This::Reverse as Split<Suffix::Reverse>>::split_ref(rev);
765        let out = (rprefix.reverse(), rsuffix.reverse());
766        // TODO!!!!
767        let out2 = unsafe { core::mem::transmute_copy(&out) };
768        core::mem::forget(out);
769        out2
770    }
771}
772
773/// Trait for Variadic of vecs, as formed by `VariadicExt::into_vec()`.
774#[cfg(feature = "std")]
775#[sealed]
776pub trait VecVariadic: VariadicExt {
777    /// Individual variadic items without the Vec wrapper
778    type UnVec: VariadicExt<IntoVec = Self>;
779
780    /// zip across all the vecs in this VariadicVec
781    fn zip_vecs(&self) -> impl Iterator<Item = <Self::UnVec as VariadicExt>::AsRefVar<'_>>;
782
783    /// append an unvec'ed Variadic into this VariadicVec
784    fn push(&mut self, item: Self::UnVec);
785
786    /// get the unvec'ed Variadic at position `index`
787    fn get(&mut self, index: usize) -> Option<<Self::UnVec as VariadicExt>::AsRefVar<'_>>;
788
789    /// result type from into_zip
790    type IntoZip: Iterator<Item = Self::UnVec>;
791    /// Turns into an iterator of items `UnVec` -- i.e. iterate through rows (not columns!).
792    fn into_zip(self) -> Self::IntoZip;
793
794    /// result type from drain
795    type Drain<'a>: Iterator<Item = Self::UnVec>
796    where
797        Self: 'a;
798    /// Turns into a Drain of items `UnVec` -- i.e. iterate through rows (not columns!).
799    fn drain<R>(&mut self, range: R) -> Self::Drain<'_>
800    where
801        R: core::ops::RangeBounds<usize> + Clone;
802}
803
804#[cfg(feature = "std")]
805#[sealed]
806impl<Item, Rest> VecVariadic for (Vec<Item>, Rest)
807where
808    Rest: VecVariadic,
809{
810    type UnVec = var_type!(Item, ...Rest::UnVec);
811
812    fn zip_vecs(&self) -> impl Iterator<Item = <Self::UnVec as VariadicExt>::AsRefVar<'_>> {
813        let (this, rest) = self;
814        core::iter::zip(this.iter(), rest.zip_vecs())
815    }
816
817    fn push(&mut self, row: Self::UnVec) {
818        let (this_vec, rest_vecs) = self;
819        let (this_col, rest_cols) = row;
820        this_vec.push(this_col);
821        rest_vecs.push(rest_cols);
822    }
823
824    fn get(&mut self, index: usize) -> Option<<Self::UnVec as VariadicExt>::AsRefVar<'_>> {
825        let (this_vec, rest_vecs) = self;
826        if let Some(rest) = VecVariadic::get(rest_vecs, index) {
827            this_vec.get(index).map(|item| var_expr!(item, ...rest))
828        } else {
829            None
830        }
831    }
832
833    type IntoZip = core::iter::Zip<alloc::vec::IntoIter<Item>, Rest::IntoZip>;
834    fn into_zip(self) -> Self::IntoZip {
835        let (this, rest) = self;
836        core::iter::zip(this, rest.into_zip())
837    }
838
839    type Drain<'a>
840        = core::iter::Zip<alloc::vec::Drain<'a, Item>, Rest::Drain<'a>>
841    where
842        Self: 'a;
843    fn drain<R>(&mut self, range: R) -> Self::Drain<'_>
844    where
845        R: core::ops::RangeBounds<usize> + Clone,
846    {
847        let (this, rest) = self;
848        core::iter::zip(this.drain(range.clone()), rest.drain(range))
849    }
850}
851
852#[cfg(feature = "std")]
853#[sealed]
854impl VecVariadic for () {
855    type UnVec = ();
856
857    fn zip_vecs(&self) -> impl Iterator<Item = <Self::UnVec as VariadicExt>::AsRefVar<'_>> {
858        core::iter::repeat(var_expr!())
859    }
860
861    fn push(&mut self, _item: Self::UnVec) {}
862
863    fn get(&mut self, _index: usize) -> Option<<Self::UnVec as VariadicExt>::AsRefVar<'_>> {
864        Some(())
865    }
866
867    type IntoZip = core::iter::Repeat<var_type!()>;
868    fn into_zip(self) -> Self::IntoZip {
869        core::iter::repeat(var_expr!())
870    }
871
872    type Drain<'a>
873        = core::iter::Repeat<var_type!()>
874    where
875        Self: 'a;
876    fn drain<R>(&mut self, _range: R) -> Self::Drain<'_>
877    where
878        R: core::ops::RangeBounds<usize> + Clone,
879    {
880        core::iter::repeat(var_expr!())
881    }
882}
883
884#[cfg(test)]
885mod test {
886    use super::*;
887
888    type MyList = var_type!(u8, u16, u32, u64);
889    type MyPrefix = var_type!(u8, u16);
890    type MySuffix = <MyList as Split<MyPrefix>>::Suffix;
891
892    const _: MySuffix = var_expr!(0_u32, 0_u64);
893
894    #[test]
895    // #[expect(clippy::let_unit_value, reason = "var_expr macro test")]
896    fn test_basic_expr() {
897        let _ = var_expr!();
898        let _ = var_expr!(1);
899        let _ = var_expr!(1, "b",);
900        let _ = var_expr!("a",);
901        let _ = var_expr!(false, true, 1 + 2);
902    }
903
904    // commented out because neither #[allow(dead_code)] nor #[expect(dead_code)] made clippy happy
905    // variadic_trait! {
906    //     /// Variaidic list of futures.
907    //     pub variadic<F> FuturesList where F: core::future::Future {
908    //     }
909    // }
910
911    type _ListA = var_type!(u32, u8, i32);
912    type _ListB = var_type!(..._ListA, bool, Option<()>);
913    type _ListC = var_type!(..._ListA, bool, Option::<()>);
914
915    #[test]
916    fn test_as_ref_var() {
917        let my_owned = var_expr!("Hello".to_owned(), Box::new(5));
918        let my_ref_a = my_owned.as_ref_var();
919        let my_ref_b = my_owned.as_ref_var();
920        assert_eq!(my_ref_a, my_ref_b);
921    }
922
923    #[test]
924    fn test_as_mut_var() {
925        let mut my_owned = var_expr!("Hello".to_owned(), Box::new(5));
926        let var_args!(mut_str, mut_box) = my_owned.as_mut_var();
927        *mut_str += " World";
928        *mut_box.as_mut() += 1;
929
930        assert_eq!(var_expr!("Hello World".to_owned(), Box::new(6)), my_owned);
931    }
932
933    #[test]
934    fn test_iter_any() {
935        let mut var = var_expr!(1_i32, false, "Hello".to_owned());
936
937        let mut mut_iter = var.iter_any_mut();
938        *mut_iter.next().unwrap().downcast_mut::<i32>().unwrap() += 1;
939        *mut_iter.next().unwrap().downcast_mut::<bool>().unwrap() |= true;
940        *mut_iter.next().unwrap().downcast_mut::<String>().unwrap() += " World";
941        assert!(mut_iter.next().is_none());
942
943        let mut ref_iter = var.iter_any_ref();
944        assert_eq!(
945            Some(&2),
946            ref_iter
947                .next()
948                .map(<dyn Any>::downcast_ref)
949                .map(Option::unwrap)
950        );
951        assert_eq!(
952            Some(&true),
953            ref_iter
954                .next()
955                .map(<dyn Any>::downcast_ref)
956                .map(Option::unwrap)
957        );
958        assert_eq!(
959            Some("Hello World"),
960            ref_iter
961                .next()
962                .map(|any| &**any.downcast_ref::<String>().unwrap())
963        );
964        assert!(ref_iter.next().is_none());
965    }
966
967    #[test]
968    fn test_homogenous_get() {
969        let mut var = var_expr!(0, 1, 2, 3, 4);
970        for i in 0..5 {
971            assert_eq!(Some(i), var.get(i).copied());
972            assert_eq!(Some(i), var.get_mut(i).copied());
973        }
974    }
975
976    #[cfg(feature = "std")]
977    #[test]
978    fn test_into_vec() {
979        use crate::VecVariadic;
980
981        type Item = var_type!(i32, String);
982        let first: Item = var_expr!(1, "Joe".to_owned());
983        let second: Item = var_expr!(2, "Mingwei".to_owned());
984        let mut column_store = first.clone().into_singleton_vec();
985        column_store.push(second.clone());
986        assert_eq!(column_store.len(), 2);
987        assert_eq!(column_store.get(0).unwrap(), first.as_ref_var());
988        assert_eq!(column_store.get(1).unwrap(), second.as_ref_var());
989    }
990}
991
992#[test]
993fn test_eq_ref_vec() {
994    type MyVar = var_type!(i32, bool, &'static str);
995    let vec: Vec<MyVar> = vec![
996        var_expr!(0, true, "hello"),
997        var_expr!(1, true, "world"),
998        var_expr!(2, false, "goodnight"),
999        var_expr!(3, false, "moon"),
1000    ];
1001    let needle: <MyVar as VariadicExt>::AsRefVar<'_> =
1002        var_expr!(2, false, "goodnight").as_ref_var();
1003    assert_eq!(
1004        Some(2),
1005        vec.iter()
1006            .position(|item| <MyVar as PartialEqVariadic>::eq_ref(needle, item.as_ref_var()))
1007    );
1008
1009    let missing: <MyVar as VariadicExt>::AsRefVar<'_> =
1010        var_expr!(3, false, "goodnight").as_ref_var();
1011    assert_eq!(
1012        None,
1013        vec.iter()
1014            .position(|item| <MyVar as PartialEqVariadic>::eq_ref(missing, item.as_ref_var()))
1015    );
1016}
1017
1018#[test]
1019fn clone_var_test() {
1020    let ref_var = var_expr!(&1, &format!("hello {}", "world"), &vec![1, 2, 3]);
1021    let clone_var = CloneVariadic::clone_ref_var(ref_var);
1022    assert_eq!(
1023        var_expr!(1, "hello world".to_owned(), vec![1, 2, 3]),
1024        clone_var
1025    );
1026}