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    type IntoVec = (Vec<Item>, Rest::IntoVec);
291    fn into_singleton_vec(self) -> Self::IntoVec {
292        let var_args!(item, ...rest) = self;
293        var_expr!(vec!(item), ...rest.into_singleton_vec())
294    }
295}
296
297#[sealed]
298impl VariadicExt for () {
299    const LEN: usize = 0;
300
301    type Extend<Suffix>
302        = Suffix
303    where
304        Suffix: VariadicExt;
305    fn extend<Suffix>(self, suffix: Suffix) -> Self::Extend<Suffix>
306    where
307        Suffix: VariadicExt,
308    {
309        suffix
310    }
311
312    type Reverse = ();
313    fn reverse(self) -> Self::Reverse {}
314    fn reverse_ref(_this: Self::AsRefVar<'_>) -> <Self::Reverse as VariadicExt>::AsRefVar<'_> {}
315
316    type AsRefVar<'a> = ();
317    fn as_ref_var(&self) -> Self::AsRefVar<'_> {}
318
319    type AsMutVar<'a> = ();
320    fn as_mut_var(&mut self) -> Self::AsMutVar<'_> {}
321
322    type IterAnyRef<'a>
323        = core::iter::Empty<&'a dyn Any>
324    where
325        Self: 'static;
326    fn iter_any_ref(&self) -> Self::IterAnyRef<'_>
327    where
328        Self: 'static,
329    {
330        core::iter::empty()
331    }
332
333    type IterAnyMut<'a>
334        = core::iter::Empty<&'a mut dyn Any>
335    where
336        Self: 'static;
337    fn iter_any_mut(&mut self) -> Self::IterAnyMut<'_>
338    where
339        Self: 'static,
340    {
341        core::iter::empty()
342    }
343
344    type IntoOption = ();
345    fn into_option(self) -> Self::IntoOption {}
346
347    type IntoVec = ();
348    fn into_singleton_vec(self) -> Self::IntoVec {}
349}
350
351/// A variadic of either shared references, exclusive references, or both.
352///
353/// Provides the [`Self::UnRefVar`] associated type which is the original variadic of owned values.
354///
355/// This is a sealed trait.
356#[sealed]
357pub trait EitherRefVariadic: VariadicExt {
358    /// The un-referenced variadic. Each item will have one layer of shared references removed.
359    ///
360    /// The inverse of [`VariadicExt::AsRefVar`] and [`VariadicExt::AsMutVar`].
361    ///
362    /// ```rust
363    /// # use variadics::*;
364    /// let un_ref: <var_type!(&u32, &String, &bool) as EitherRefVariadic>::UnRefVar =
365    ///     var_expr!(1_u32, "Hello".to_owned(), false);
366    /// ```
367    type UnRefVar: VariadicExt;
368
369    /// This type with all exclusive `&mut` references replaced with shared `&` references.
370    ///
371    /// Returned by [`Self::mut_to_ref`].
372    type RefVar: RefVariadic<UnRefVar = Self::UnRefVar, RefVar = Self::RefVar>;
373    /// Convert all exclusive (`mut`) references into shared references: [`RefVariadic`].
374    ///
375    /// ```rust
376    /// # use variadics::*;
377    /// let mut original = var_expr!(1_u32, "Hello".to_owned(), false);
378    /// let as_mut: var_type!(&mut u32, &mut String, &mut bool) = original.as_mut_var();
379    /// let as_ref_1: var_type!(&u32, &String, &bool) = as_mut.mut_to_ref();
380    /// let as_ref_2: var_type!(&u32, &String, &bool) = as_ref_1; // Can copy the reference version.
381    /// drop((as_ref_1, as_ref_2));
382    /// ```
383    fn mut_to_ref(self) -> Self::RefVar;
384
385    /// This type with all shared `&` references replaced with exclusive references `&mut`.
386    ///
387    /// Conversion from `&` to `&mut` is generally invalid, so a `ref_to_mut()` method does not exist.
388    type MutVar: MutVariadic<UnRefVar = Self::UnRefVar, MutVar = Self::MutVar>;
389
390    /// convert entries to [`<UnRefVar as VariadicExt>::AsRefVar`](VariadicExt::AsRefVar)
391    fn unref_ref(&self) -> <Self::UnRefVar as VariadicExt>::AsRefVar<'_>;
392}
393#[sealed]
394impl<'a, Item, Rest> EitherRefVariadic for (&'a Item, Rest)
395where
396    Rest: EitherRefVariadic,
397{
398    type UnRefVar = (Item, Rest::UnRefVar);
399
400    type RefVar = (&'a Item, Rest::RefVar);
401    fn mut_to_ref(self) -> Self::RefVar {
402        let var_args!(item, ...rest) = self;
403        var_expr!(item, ...rest.mut_to_ref())
404    }
405
406    type MutVar = (&'a mut Item, Rest::MutVar);
407
408    fn unref_ref(&self) -> <Self::UnRefVar as VariadicExt>::AsRefVar<'_> {
409        let var_args!(item, ...rest) = self;
410        var_expr!(item, ...rest.unref_ref())
411    }
412}
413#[sealed]
414impl<'a, Item, Rest> EitherRefVariadic for (&'a mut Item, Rest)
415where
416    Rest: EitherRefVariadic,
417{
418    type UnRefVar = (Item, Rest::UnRefVar);
419
420    type RefVar = (&'a Item, Rest::RefVar);
421    fn mut_to_ref(self) -> Self::RefVar {
422        let var_args!(item, ...rest) = self;
423        var_expr!(&*item, ...rest.mut_to_ref())
424    }
425
426    type MutVar = (&'a mut Item, Rest::MutVar);
427
428    fn unref_ref(&self) -> <Self::UnRefVar as VariadicExt>::AsRefVar<'_> {
429        let var_args!(item, ...rest) = self;
430        var_expr!(item, ...rest.unref_ref())
431    }
432}
433#[sealed]
434impl EitherRefVariadic for () {
435    type UnRefVar = ();
436
437    type RefVar = ();
438    fn mut_to_ref(self) -> Self::RefVar {}
439
440    type MutVar = ();
441
442    fn unref_ref(&self) -> <Self::UnRefVar as VariadicExt>::AsRefVar<'_> {}
443}
444
445/// A variadic where each item is a shared reference `&item`.
446///
447/// This can be created using [`VariadicExt::as_ref_var`]:
448/// ```rust
449/// # use variadics::*;
450/// let as_ref: var_type!(&u32, &String, &bool) =
451///     var_expr!(1_u32, "Hello".to_owned(), false).as_ref_var();
452/// ```
453///
454/// This is a sealed trait.
455#[sealed]
456pub trait RefVariadic: EitherRefVariadic<RefVar = Self>
457where
458    Self: Copy,
459{
460}
461#[sealed]
462impl<Item, Rest> RefVariadic for (&Item, Rest) where Rest: RefVariadic {}
463#[sealed]
464impl RefVariadic for () {}
465
466/// A variadic where each item is an exclusive reference `&mut item`.
467///
468/// This can be created using [`VariadicExt::as_mut_var`]:
469/// ```rust
470/// # use variadics::*;
471/// let as_mut: var_type!(&mut u32, &mut String, &mut bool) =
472///     var_expr!(1_u32, "Hello".to_owned(), false).as_mut_var();
473/// ```
474///
475/// This is a sealed trait.
476#[sealed]
477pub trait MutVariadic: EitherRefVariadic<MutVar = Self> {}
478#[sealed]
479impl<Item, Rest> MutVariadic for (&mut Item, Rest) where Rest: MutVariadic {}
480#[sealed]
481impl MutVariadic for () {}
482
483/// Copy a variadic of references [`EitherRefVariadic`] into a variadic of owned values [`EitherRefVariadic::UnRefVar`].
484///
485/// ```rust
486/// # use variadics::*;
487/// let ref_var = var_expr!(&1, &"hello", &false);
488/// let copy_var = ref_var.copy_var();
489/// assert_eq!(var_expr!(1, "hello", false), copy_var);
490/// ```
491#[sealed]
492pub trait CopyRefVariadic: EitherRefVariadic {
493    /// Copy self per-value.
494    fn copy_var(&self) -> Self::UnRefVar;
495}
496#[sealed]
497impl<Item, Rest> CopyRefVariadic for (&Item, Rest)
498where
499    Item: Copy,
500    Rest: CopyRefVariadic,
501{
502    fn copy_var(&self) -> Self::UnRefVar {
503        let &var_args!(&item, ...ref rest) = self;
504        var_expr!(item, ...rest.copy_var())
505    }
506}
507#[sealed]
508impl<Item, Rest> CopyRefVariadic for (&mut Item, Rest)
509where
510    Item: Copy,
511    Rest: CopyRefVariadic,
512{
513    fn copy_var(&self) -> Self::UnRefVar {
514        let &var_args!(&mut item, ...ref rest) = self;
515        var_expr!(item, ...rest.copy_var())
516    }
517}
518#[sealed]
519impl CopyRefVariadic for () {
520    fn copy_var(&self) -> Self::UnRefVar {}
521}
522
523/// Clone a variadic of references [`AsRefVar`](VariadicExt::AsRefVar) into a variadic of owned values.
524///
525/// ```rust
526/// # use variadics::*;
527/// let ref_var = var_expr!(&1, &format!("hello {}", "world"), &vec![1, 2, 3]);
528/// let clone_var = CloneVariadic::clone_ref_var(ref_var);
529/// assert_eq!(
530///     var_expr!(1, "hello world".to_owned(), vec![1, 2, 3]),
531///     clone_var
532/// );
533/// ```
534#[sealed]
535pub trait CloneVariadic: VariadicExt + Clone {
536    /// Clone a variadic of references [`AsRefVar`](VariadicExt::AsRefVar) into a variadic of owned values.
537    fn clone_ref_var(this: Self::AsRefVar<'_>) -> Self;
538}
539#[sealed]
540impl<Item, Rest> CloneVariadic for (Item, Rest)
541where
542    Item: Clone,
543    Rest: CloneVariadic,
544{
545    fn clone_ref_var(this: Self::AsRefVar<'_>) -> Self {
546        let var_args!(item, ...rest) = this;
547        var_expr!(item.clone(), ...Rest::clone_ref_var(rest))
548    }
549}
550#[sealed]
551impl CloneVariadic for () {
552    fn clone_ref_var(_this: Self::AsRefVar<'_>) -> Self {}
553}
554
555/// A variadic where all item implement [`PartialEq`].
556#[sealed]
557pub trait PartialEqVariadic: VariadicExt {
558    /// `PartialEq` between a referenced variadic and a variadic of references, of the same types.
559    fn eq(&self, other: &Self) -> bool;
560
561    /// `PartialEq` for the `AsRefVar` version op `Self`.
562    fn eq_ref(this: Self::AsRefVar<'_>, other: Self::AsRefVar<'_>) -> bool;
563}
564#[sealed]
565impl<Item, Rest> PartialEqVariadic for (Item, Rest)
566where
567    Item: PartialEq,
568    Rest: PartialEqVariadic,
569{
570    fn eq(&self, other: &Self) -> bool {
571        let var_args!(item_self, ...rest_self) = self;
572        let var_args!(item_other, ...rest_other) = other;
573        item_self == item_other && rest_self.eq(rest_other)
574    }
575
576    fn eq_ref(
577        this: <Self as VariadicExt>::AsRefVar<'_>,
578        other: <Self as VariadicExt>::AsRefVar<'_>,
579    ) -> bool {
580        let var_args!(item_self, ...rest_self) = this;
581        let var_args!(item_other, ...rest_other) = other;
582        item_self == item_other && Rest::eq_ref(rest_self, rest_other)
583    }
584}
585#[sealed]
586impl PartialEqVariadic for () {
587    fn eq(&self, _other: &Self) -> bool {
588        true
589    }
590
591    fn eq_ref(
592        _this: <Self as VariadicExt>::AsRefVar<'_>,
593        _other: <Self as VariadicExt>::AsRefVar<'_>,
594    ) -> bool {
595        true
596    }
597}
598
599/// A variadic where all elements are the same type, `T`.
600///
601/// This is a sealed trait.
602#[sealed]
603pub trait HomogenousVariadic<T>: Variadic {
604    /// Returns a reference to an element.
605    fn get(&self, i: usize) -> Option<&T>;
606    /// Returns an exclusive reference to an element.
607    fn get_mut(&mut self, i: usize) -> Option<&mut T>;
608
609    /// Iterator type returned by `into_iter`.
610    type IntoIter: Iterator<Item = T>;
611    /// Turns this `HomogenousVariadic<T>` into an iterator of items `T`.
612    fn into_iter(self) -> Self::IntoIter;
613}
614#[sealed]
615impl<T> HomogenousVariadic<T> for () {
616    fn get(&self, _i: usize) -> Option<&T> {
617        None
618    }
619    fn get_mut(&mut self, _i: usize) -> Option<&mut T> {
620        None
621    }
622
623    type IntoIter = core::iter::Empty<T>;
624    fn into_iter(self) -> Self::IntoIter {
625        core::iter::empty()
626    }
627}
628#[sealed]
629impl<T, Rest> HomogenousVariadic<T> for (T, Rest)
630where
631    Rest: HomogenousVariadic<T>,
632{
633    fn get(&self, i: usize) -> Option<&T> {
634        let (item, rest) = self;
635        if i == 0 { Some(item) } else { rest.get(i - 1) }
636    }
637    fn get_mut(&mut self, i: usize) -> Option<&mut T> {
638        let (item, rest) = self;
639        if i == 0 {
640            Some(item)
641        } else {
642            rest.get_mut(i - 1)
643        }
644    }
645
646    type IntoIter = core::iter::Chain<core::iter::Once<T>, Rest::IntoIter>;
647    fn into_iter(self) -> Self::IntoIter {
648        let (item, rest) = self;
649        core::iter::once(item).chain(rest.into_iter())
650    }
651}
652
653/// Helper trait for splitting a variadic into two parts. `Prefix` is the first part, everything
654/// after is the `Suffix` or second part.
655///
656/// This is a sealed trait.
657#[sealed]
658pub trait Split<Prefix>: VariadicExt
659where
660    Prefix: VariadicExt,
661{
662    /// The second part when splitting this variadic by `Prefix`.
663    type Suffix: VariadicExt;
664    /// Splits this variadic into two parts, first the `Prefix`, and second the `Suffix`.
665    fn split(self) -> (Prefix, Self::Suffix);
666    /// Splits a refvar variadic
667    fn split_ref(
668        this: Self::AsRefVar<'_>,
669    ) -> (
670        Prefix::AsRefVar<'_>,
671        <Self::Suffix as VariadicExt>::AsRefVar<'_>,
672    );
673}
674#[sealed]
675impl<Item, Rest, PrefixRest> Split<(Item, PrefixRest)> for (Item, Rest)
676where
677    PrefixRest: VariadicExt,
678    Rest: Split<PrefixRest>,
679{
680    /// The second part when splitting this variadic by `Prefix`.
681    type Suffix = <Rest as Split<PrefixRest>>::Suffix;
682    /// Splits this variadic into two parts, first the `Prefix`, and second the `Suffix`.
683    fn split(self) -> ((Item, PrefixRest), Self::Suffix) {
684        let (item, rest) = self;
685        let (prefix_rest, suffix) = rest.split();
686        ((item, prefix_rest), suffix)
687    }
688    /// Splits a refvar variadic
689    fn split_ref(
690        this: Self::AsRefVar<'_>,
691    ) -> (
692        <(Item, PrefixRest) as VariadicExt>::AsRefVar<'_>,
693        <Self::Suffix as VariadicExt>::AsRefVar<'_>,
694    ) {
695        let (item, rest) = this;
696        let (prefix_rest, suffix) = Rest::split_ref(rest);
697        ((item, prefix_rest), suffix)
698    }
699}
700#[sealed]
701impl<Rest> Split<var_type!()> for Rest
702where
703    Rest: VariadicExt,
704{
705    type Suffix = Rest;
706    fn split(self) -> (var_type!(), Self::Suffix) {
707        (var_expr!(), self)
708    }
709    fn split_ref(
710        this: Self::AsRefVar<'_>,
711    ) -> (var_type!(), <Self::Suffix as VariadicExt>::AsRefVar<'_>) {
712        (var_expr!(), this)
713    }
714}
715
716#[sealed]
717/// Helper trait for splitting a variadic into two parts. `Prefix` is the first part, everything
718/// after is the `Suffix` or second part.
719///
720/// This is a sealed trait.
721pub trait SplitBySuffix<Suffix>: VariadicExt
722where
723    Suffix: VariadicExt,
724{
725    /// The first part when splitting this variadic by `Suffix`.
726    type Prefix: VariadicExt;
727    /// Splits this variadic into two parts, first the `Prefix`, and second the `Suffix`.
728    fn split_by_suffix(self) -> (Self::Prefix, Suffix);
729    /// Splits a refvar variadic
730    fn split_by_suffix_ref(
731        this: Self::AsRefVar<'_>,
732    ) -> (
733        <Self::Prefix as VariadicExt>::AsRefVar<'_>,
734        Suffix::AsRefVar<'_>,
735    );
736}
737#[sealed]
738impl<Suffix, This> SplitBySuffix<Suffix> for This
739where
740    Suffix: VariadicExt,
741    This: VariadicExt,
742    This::Reverse: Split<Suffix::Reverse>,
743    Suffix::Reverse: VariadicExt<Reverse = Suffix>,
744{
745    /// The second part when splitting this variadic by `Prefix`.
746    type Prefix = <<This::Reverse as Split<Suffix::Reverse>>::Suffix as VariadicExt>::Reverse;
747    /// Splits this variadic into two parts, first the `Prefix`, and second the `Suffix`.
748    fn split_by_suffix(self) -> (Self::Prefix, Suffix) {
749        let (rsuffix, rprefix) = self.reverse().split();
750        (rprefix.reverse(), rsuffix.reverse())
751    }
752
753    fn split_by_suffix_ref(
754        this: Self::AsRefVar<'_>,
755    ) -> (
756        <Self::Prefix as VariadicExt>::AsRefVar<'_>,
757        Suffix::AsRefVar<'_>,
758    ) {
759        let rev = This::reverse_ref(this);
760        let (rsuffix, rprefix) = <This::Reverse as Split<Suffix::Reverse>>::split_ref(rev);
761        let out = (rprefix.reverse(), rsuffix.reverse());
762        // TODO!!!!
763        let out2 = unsafe { core::mem::transmute_copy(&out) };
764        core::mem::forget(out);
765        out2
766    }
767}
768
769/// trait for Variadic of vecs, as formed by `VariadicExt::into_vec()`
770#[sealed]
771pub trait VecVariadic: VariadicExt {
772    /// Individual variadic items without the Vec wrapper
773    type UnVec: VariadicExt<IntoVec = Self>;
774
775    /// zip across all the vecs in this VariadicVec
776    fn zip_vecs(&self) -> impl Iterator<Item = <Self::UnVec as VariadicExt>::AsRefVar<'_>>;
777
778    /// append an unvec'ed Variadic into this VariadicVec
779    fn push(&mut self, item: Self::UnVec);
780
781    /// get the unvec'ed Variadic at position `index`
782    fn get(&mut self, index: usize) -> Option<<Self::UnVec as VariadicExt>::AsRefVar<'_>>;
783
784    /// result type from into_zip
785    type IntoZip: Iterator<Item = Self::UnVec>;
786    /// Turns into an iterator of items `UnVec` -- i.e. iterate through rows (not columns!).
787    fn into_zip(self) -> Self::IntoZip;
788
789    /// result type from drain
790    type Drain<'a>: Iterator<Item = Self::UnVec>
791    where
792        Self: 'a;
793    /// Turns into a Drain of items `UnVec` -- i.e. iterate through rows (not columns!).
794    fn drain<R>(&mut self, range: R) -> Self::Drain<'_>
795    where
796        R: core::ops::RangeBounds<usize> + Clone;
797}
798
799#[sealed]
800impl<Item, Rest> VecVariadic for (Vec<Item>, Rest)
801where
802    Rest: VecVariadic,
803{
804    type UnVec = var_type!(Item, ...Rest::UnVec);
805
806    fn zip_vecs(&self) -> impl Iterator<Item = <Self::UnVec as VariadicExt>::AsRefVar<'_>> {
807        let (this, rest) = self;
808        core::iter::zip(this.iter(), rest.zip_vecs())
809    }
810
811    fn push(&mut self, row: Self::UnVec) {
812        let (this_vec, rest_vecs) = self;
813        let (this_col, rest_cols) = row;
814        this_vec.push(this_col);
815        rest_vecs.push(rest_cols);
816    }
817
818    fn get(&mut self, index: usize) -> Option<<Self::UnVec as VariadicExt>::AsRefVar<'_>> {
819        let (this_vec, rest_vecs) = self;
820        if let Some(rest) = VecVariadic::get(rest_vecs, index) {
821            this_vec.get(index).map(|item| var_expr!(item, ...rest))
822        } else {
823            None
824        }
825    }
826
827    type IntoZip = core::iter::Zip<alloc::vec::IntoIter<Item>, Rest::IntoZip>;
828    fn into_zip(self) -> Self::IntoZip {
829        let (this, rest) = self;
830        core::iter::zip(this, rest.into_zip())
831    }
832
833    type Drain<'a>
834        = core::iter::Zip<alloc::vec::Drain<'a, Item>, Rest::Drain<'a>>
835    where
836        Self: 'a;
837    fn drain<R>(&mut self, range: R) -> Self::Drain<'_>
838    where
839        R: core::ops::RangeBounds<usize> + Clone,
840    {
841        let (this, rest) = self;
842        core::iter::zip(this.drain(range.clone()), rest.drain(range))
843    }
844}
845
846#[sealed]
847impl VecVariadic for var_type!() {
848    type UnVec = var_type!();
849
850    fn zip_vecs(&self) -> impl Iterator<Item = <Self::UnVec as VariadicExt>::AsRefVar<'_>> {
851        core::iter::repeat(var_expr!())
852    }
853
854    fn push(&mut self, _item: Self::UnVec) {}
855
856    fn get(&mut self, _index: usize) -> Option<<Self::UnVec as VariadicExt>::AsRefVar<'_>> {
857        Some(())
858    }
859
860    type IntoZip = core::iter::Repeat<var_type!()>;
861    fn into_zip(self) -> Self::IntoZip {
862        core::iter::repeat(var_expr!())
863    }
864
865    type Drain<'a>
866        = core::iter::Repeat<var_type!()>
867    where
868        Self: 'a;
869    fn drain<R>(&mut self, _range: R) -> Self::Drain<'_>
870    where
871        R: core::ops::RangeBounds<usize> + Clone,
872    {
873        core::iter::repeat(var_expr!())
874    }
875}
876
877#[cfg(test)]
878mod test {
879    use super::*;
880
881    type MyList = var_type!(u8, u16, u32, u64);
882    type MyPrefix = var_type!(u8, u16);
883    type MySuffix = <MyList as Split<MyPrefix>>::Suffix;
884
885    const _: MySuffix = var_expr!(0_u32, 0_u64);
886
887    #[test]
888    // #[expect(clippy::let_unit_value, reason = "var_expr macro test")]
889    fn test_basic_expr() {
890        let _ = var_expr!();
891        let _ = var_expr!(1);
892        let _ = var_expr!(1, "b",);
893        let _ = var_expr!("a",);
894        let _ = var_expr!(false, true, 1 + 2);
895    }
896
897    // commented out because neither #[allow(dead_code)] nor #[expect(dead_code)] made clippy happy
898    // variadic_trait! {
899    //     /// Variaidic list of futures.
900    //     pub variadic<F> FuturesList where F: core::future::Future {
901    //     }
902    // }
903
904    type _ListA = var_type!(u32, u8, i32);
905    type _ListB = var_type!(..._ListA, bool, Option<()>);
906    type _ListC = var_type!(..._ListA, bool, Option::<()>);
907
908    #[test]
909    fn test_as_ref_var() {
910        let my_owned = var_expr!("Hello".to_owned(), Box::new(5));
911        let my_ref_a = my_owned.as_ref_var();
912        let my_ref_b = my_owned.as_ref_var();
913        assert_eq!(my_ref_a, my_ref_b);
914    }
915
916    #[test]
917    fn test_as_mut_var() {
918        let mut my_owned = var_expr!("Hello".to_owned(), Box::new(5));
919        let var_args!(mut_str, mut_box) = my_owned.as_mut_var();
920        *mut_str += " World";
921        *mut_box.as_mut() += 1;
922
923        assert_eq!(var_expr!("Hello World".to_owned(), Box::new(6)), my_owned);
924    }
925
926    #[test]
927    fn test_iter_any() {
928        let mut var = var_expr!(1_i32, false, "Hello".to_owned());
929
930        let mut mut_iter = var.iter_any_mut();
931        *mut_iter.next().unwrap().downcast_mut::<i32>().unwrap() += 1;
932        *mut_iter.next().unwrap().downcast_mut::<bool>().unwrap() |= true;
933        *mut_iter.next().unwrap().downcast_mut::<String>().unwrap() += " World";
934        assert!(mut_iter.next().is_none());
935
936        let mut ref_iter = var.iter_any_ref();
937        assert_eq!(
938            Some(&2),
939            ref_iter
940                .next()
941                .map(<dyn Any>::downcast_ref)
942                .map(Option::unwrap)
943        );
944        assert_eq!(
945            Some(&true),
946            ref_iter
947                .next()
948                .map(<dyn Any>::downcast_ref)
949                .map(Option::unwrap)
950        );
951        assert_eq!(
952            Some("Hello World"),
953            ref_iter
954                .next()
955                .map(|any| &**any.downcast_ref::<String>().unwrap())
956        );
957        assert!(ref_iter.next().is_none());
958    }
959
960    #[test]
961    fn test_homogenous_get() {
962        let mut var = var_expr!(0, 1, 2, 3, 4);
963        for i in 0..5 {
964            assert_eq!(Some(i), var.get(i).copied());
965            assert_eq!(Some(i), var.get_mut(i).copied());
966        }
967    }
968
969    #[test]
970    fn test_into_vec() {
971        use crate::VecVariadic;
972
973        type Item = var_type!(i32, String);
974        let first: Item = var_expr!(1, "Joe".to_string());
975        let second: Item = var_expr!(2, "Mingwei".to_string());
976        let mut column_store = first.clone().into_singleton_vec();
977        column_store.push(second.clone());
978        assert_eq!(column_store.len(), 2);
979        assert_eq!(column_store.get(0).unwrap(), first.as_ref_var());
980        assert_eq!(column_store.get(1).unwrap(), second.as_ref_var());
981    }
982}
983
984#[test]
985fn test_eq_ref_vec() {
986    type MyVar = var_type!(i32, bool, &'static str);
987    let vec: Vec<MyVar> = vec![
988        var_expr!(0, true, "hello"),
989        var_expr!(1, true, "world"),
990        var_expr!(2, false, "goodnight"),
991        var_expr!(3, false, "moon"),
992    ];
993    let needle: <MyVar as VariadicExt>::AsRefVar<'_> =
994        var_expr!(2, false, "goodnight").as_ref_var();
995    assert_eq!(
996        Some(2),
997        vec.iter()
998            .position(|item| <MyVar as PartialEqVariadic>::eq_ref(needle, item.as_ref_var()))
999    );
1000
1001    let missing: <MyVar as VariadicExt>::AsRefVar<'_> =
1002        var_expr!(3, false, "goodnight").as_ref_var();
1003    assert_eq!(
1004        None,
1005        vec.iter()
1006            .position(|item| <MyVar as PartialEqVariadic>::eq_ref(missing, item.as_ref_var()))
1007    );
1008}
1009
1010#[test]
1011fn clone_var_test() {
1012    let ref_var = var_expr!(&1, &format!("hello {}", "world"), &vec![1, 2, 3]);
1013    let clone_var = CloneVariadic::clone_ref_var(ref_var);
1014    assert_eq!(
1015        var_expr!(1, "hello world".to_owned(), vec![1, 2, 3]),
1016        clone_var
1017    );
1018}