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