1#![warn(missing_docs)]
2#![doc = include_str!("../README.md")]
3#![doc = include_str!("../var_expr.md")]
9#![doc = include_str!("../var_type.md")]
11#![doc = include_str!("../var_args.md")]
13
14pub 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#[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#[sealed]
103pub trait Variadic {}
104#[sealed]
105impl<Item, Rest> Variadic for (Item, Rest) where Rest: Variadic {}
106#[sealed]
107impl Variadic for () {}
108
109#[sealed]
113pub trait VariadicExt: Variadic {
114 const LEN: usize;
116
117 type Extend<Suffix>: VariadicExt
119 where
120 Suffix: VariadicExt;
121 fn extend<Suffix>(self, suffix: Suffix) -> Self::Extend<Suffix>
123 where
124 Suffix: VariadicExt;
125
126 type Reverse: VariadicExt;
128 fn reverse(self) -> Self::Reverse;
130 fn reverse_ref(this: Self::AsRefVar<'_>) -> <Self::Reverse as VariadicExt>::AsRefVar<'_>;
132
133 fn len(&self) -> usize {
135 Self::LEN
136 }
137
138 fn is_empty(&self) -> bool {
140 Self::LEN == 0
141 }
142
143 type AsRefVar<'a>: RefVariadic<UnRefVar = Self, RefVar = Self::AsRefVar<'a>, MutVar = Self::AsMutVar<'a>>
145 where
146 Self: 'a;
147 fn as_ref_var(&self) -> Self::AsRefVar<'_>;
154
155 type AsMutVar<'a>: MutVariadic<UnRefVar = Self, RefVar = Self::AsRefVar<'a>, MutVar = Self::AsMutVar<'a>>
157 where
158 Self: 'a;
159 fn as_mut_var(&mut self) -> Self::AsMutVar<'_>;
167
168 type IterAnyRef<'a>: Iterator<Item = &'a dyn Any>
170 where
171 Self: 'static;
172 fn iter_any_ref(&self) -> Self::IterAnyRef<'_>
174 where
175 Self: 'static;
176
177 type IterAnyMut<'a>: Iterator<Item = &'a mut dyn Any>
179 where
180 Self: 'static;
181 fn iter_any_mut(&mut self) -> Self::IterAnyMut<'_>
183 where
184 Self: 'static;
185
186 type IntoOption;
188 fn into_option(self) -> Self::IntoOption;
190
191 type IntoVec: VecVariadic<UnVec = Self> + Default;
193 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 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#[sealed]
347pub trait EitherRefVariadic: VariadicExt {
348 type UnRefVar: VariadicExt;
358
359 type RefVar: RefVariadic<UnRefVar = Self::UnRefVar, RefVar = Self::RefVar>;
363 fn mut_to_ref(self) -> Self::RefVar;
374
375 type MutVar: MutVariadic<UnRefVar = Self::UnRefVar, MutVar = Self::MutVar>;
379
380 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#[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#[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#[sealed]
482pub trait CopyRefVariadic: EitherRefVariadic {
483 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#[sealed]
525pub trait CloneVariadic: VariadicExt + Clone {
526 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#[sealed]
547pub trait PartialEqVariadic: VariadicExt {
548 fn eq(&self, other: &Self) -> bool;
550
551 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#[sealed]
593pub trait HomogenousVariadic<T>: Variadic {
594 fn get(&self, i: usize) -> Option<&T>;
596 fn get_mut(&mut self, i: usize) -> Option<&mut T>;
598
599 type IntoIter: Iterator<Item = T>;
601 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#[sealed]
648pub trait Split<Prefix>: VariadicExt
649where
650 Prefix: VariadicExt,
651{
652 type Suffix: VariadicExt;
654 fn split(self) -> (Prefix, Self::Suffix);
656 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 type Suffix = <Rest as Split<PrefixRest>>::Suffix;
672 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 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]
707pub trait SplitBySuffix<Suffix>: VariadicExt
712where
713 Suffix: VariadicExt,
714{
715 type Prefix: VariadicExt;
717 fn split_by_suffix(self) -> (Self::Prefix, Suffix);
719 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 type Prefix = <<This::Reverse as Split<Suffix::Reverse>>::Suffix as VariadicExt>::Reverse;
737 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 let out2 = unsafe { std::mem::transmute_copy(&out) };
754 std::mem::forget(out);
755 out2
756 }
757}
758
759#[sealed]
761pub trait VecVariadic: VariadicExt {
762 type UnVec: VariadicExt<IntoVec = Self>;
764
765 fn zip_vecs(&self) -> impl Iterator<Item = <Self::UnVec as VariadicExt>::AsRefVar<'_>>;
767
768 fn push(&mut self, item: Self::UnVec);
770
771 fn get(&mut self, index: usize) -> Option<<Self::UnVec as VariadicExt>::AsRefVar<'_>>;
773
774 type IntoZip: Iterator<Item = Self::UnVec>;
776 fn into_zip(self) -> Self::IntoZip;
778
779 type Drain<'a>: Iterator<Item = Self::UnVec>
781 where
782 Self: 'a;
783 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 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 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}