Skip to main content

variadics/
lib.rs

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