#![warn(missing_docs)]
#![doc = include_str!("../README.md")]
#![doc = include_str!("../var_expr.md")]
#![doc = include_str!("../var_type.md")]
#![doc = include_str!("../var_args.md")]
pub mod variadic_collections;
use std::any::Any;
use sealed::sealed;
#[doc = include_str!("../var_expr.md")]
#[macro_export]
macro_rules! var_expr {
() => ( () );
(...$a:ident $(,)? ) => ( $a );
(...$a:expr $(,)? ) => ( $a );
(...$a:ident, $( $b:tt )+) => ( $crate::VariadicExt::extend($a, $crate::var_expr!( $( $b )* )) );
(...$a:expr, $( $b:tt )+) => ( $crate::VariadicExt::extend($a, $crate::var_expr!( $( $b )* )) );
($a:ident $(,)? ) => ( ($a, ()) );
($a:expr $(,)? ) => ( ($a, ()) );
($a:ident, $( $b:tt )+) => ( ($a, $crate::var_expr!( $( $b )* )) );
($a:expr, $( $b:tt )+) => ( ($a, $crate::var_expr!( $( $b )* )) );
}
#[doc = include_str!("../var_type.md")]
#[macro_export]
macro_rules! var_type {
() => ( () );
(...$a:ty $(,)? ) => ( $a );
(...$a:ty, $( $b:tt )+) => ( <$a as $crate::VariadicExt>::Extend::<$crate::var_type!( $( $b )* )> );
($a:ty $(,)? ) => ( ($a, ()) );
($a:ty, $( $b:tt )+) => ( ($a, $crate::var_type!( $( $b )* )) );
}
#[doc = include_str!("../var_args.md")]
#[macro_export]
macro_rules! var_args {
() => ( () );
(...$a:pat $(,)? ) => ( $a );
(...$a:ty, $( $b:tt )+) => ( ::core::compile_error!("`var_args!` can only have the `...` spread syntax on the last field.") );
($a:pat $(,)? ) => ( ($a, ()) );
($a:pat, $( $b:tt )+) => ( ($a, $crate::var_args!( $( $b )* )) );
}
#[macro_export]
macro_rules! variadic_trait {
(
$( #[$( $attrs:tt )*] )*
$vis:vis variadic<$item:ident> $name:ident $( $clause:tt )*
) => {
$( #[$( $attrs )*] )*
$vis trait $name: $crate::Variadic {}
$( #[$( $attrs )*] )*
impl $name for $crate::var_type!() {}
$( #[$( $attrs )*] )*
impl<$item, __Rest: $name> $name for $crate::var_type!($item, ...__Rest) $( $clause )*
};
}
#[sealed]
pub trait Variadic {}
#[sealed]
impl<Item, Rest> Variadic for (Item, Rest) where Rest: Variadic {}
#[sealed]
impl Variadic for () {}
#[sealed]
pub trait VariadicExt: Variadic {
const LEN: usize;
type Extend<Suffix>: VariadicExt
where
Suffix: VariadicExt;
fn extend<Suffix>(self, suffix: Suffix) -> Self::Extend<Suffix>
where
Suffix: VariadicExt;
type Reverse: VariadicExt;
fn reverse(self) -> Self::Reverse;
fn reverse_ref(this: Self::AsRefVar<'_>) -> <Self::Reverse as VariadicExt>::AsRefVar<'_>;
fn len(&self) -> usize {
Self::LEN
}
fn is_empty(&self) -> bool {
Self::LEN == 0
}
type AsRefVar<'a>: RefVariadic<
UnRefVar = Self,
RefVar = Self::AsRefVar<'a>,
MutVar = Self::AsMutVar<'a>,
>
where
Self: 'a;
fn as_ref_var(&self) -> Self::AsRefVar<'_>;
type AsMutVar<'a>: MutVariadic<
UnRefVar = Self,
RefVar = Self::AsRefVar<'a>,
MutVar = Self::AsMutVar<'a>,
>
where
Self: 'a;
fn as_mut_var(&mut self) -> Self::AsMutVar<'_>;
type IterAnyRef<'a>: Iterator<Item = &'a dyn Any>
where
Self: 'static;
fn iter_any_ref(&self) -> Self::IterAnyRef<'_>
where
Self: 'static;
type IterAnyMut<'a>: Iterator<Item = &'a mut dyn Any>
where
Self: 'static;
fn iter_any_mut(&mut self) -> Self::IterAnyMut<'_>
where
Self: 'static;
type IntoOption;
fn into_option(self) -> Self::IntoOption;
type IntoVec: VecVariadic<UnVec = Self> + Default;
fn into_singleton_vec(self) -> Self::IntoVec;
}
#[sealed]
impl<Item, Rest> VariadicExt for (Item, Rest)
where
Rest: VariadicExt,
{
const LEN: usize = 1 + Rest::LEN;
type Extend<Suffix>
= (Item, Rest::Extend<Suffix>)
where
Suffix: VariadicExt;
fn extend<Suffix>(self, suffix: Suffix) -> Self::Extend<Suffix>
where
Suffix: VariadicExt,
{
let (item, rest) = self;
(item, rest.extend(suffix))
}
type Reverse = <Rest::Reverse as VariadicExt>::Extend<(Item, ())>;
fn reverse(self) -> Self::Reverse {
let (item, rest) = self;
rest.reverse().extend((item, ()))
}
fn reverse_ref(this: Self::AsRefVar<'_>) -> <Self::Reverse as VariadicExt>::AsRefVar<'_> {
let (item, rest) = this;
let out = Rest::reverse_ref(rest).extend((item, ()));
let out2 = unsafe { std::mem::transmute_copy(&out) };
std::mem::forget(out);
out2
}
type AsRefVar<'a>
= (&'a Item, Rest::AsRefVar<'a>)
where
Self: 'a;
fn as_ref_var(&self) -> Self::AsRefVar<'_> {
let (item, rest) = self;
(item, rest.as_ref_var())
}
type AsMutVar<'a>
= (&'a mut Item, Rest::AsMutVar<'a>)
where
Self: 'a;
fn as_mut_var(&mut self) -> Self::AsMutVar<'_> {
let (item, rest) = self;
(item, rest.as_mut_var())
}
type IterAnyRef<'a>
= std::iter::Chain<std::iter::Once<&'a dyn Any>, Rest::IterAnyRef<'a>>
where
Self: 'static;
fn iter_any_ref(&self) -> Self::IterAnyRef<'_>
where
Self: 'static,
{
let var_args!(item, ...rest) = self;
let item: &dyn Any = item;
std::iter::once(item).chain(rest.iter_any_ref())
}
type IterAnyMut<'a>
= std::iter::Chain<std::iter::Once<&'a mut dyn Any>, Rest::IterAnyMut<'a>>
where
Self: 'static;
fn iter_any_mut(&mut self) -> Self::IterAnyMut<'_>
where
Self: 'static,
{
let var_args!(item, ...rest) = self;
let item: &mut dyn Any = item;
std::iter::once(item).chain(rest.iter_any_mut())
}
type IntoOption = (Option<Item>, Rest::IntoOption);
fn into_option(self) -> Self::IntoOption {
let var_args!(item, ...rest) = self;
var_expr!(Some(item), ...rest.into_option())
}
type IntoVec = (Vec<Item>, Rest::IntoVec);
fn into_singleton_vec(self) -> Self::IntoVec {
let var_args!(item, ...rest) = self;
var_expr!(vec!(item), ...rest.into_singleton_vec())
}
}
#[sealed]
impl VariadicExt for () {
const LEN: usize = 0;
type Extend<Suffix>
= Suffix
where
Suffix: VariadicExt;
fn extend<Suffix>(self, suffix: Suffix) -> Self::Extend<Suffix>
where
Suffix: VariadicExt,
{
suffix
}
type Reverse = ();
fn reverse(self) -> Self::Reverse {}
fn reverse_ref(_this: Self::AsRefVar<'_>) -> <Self::Reverse as VariadicExt>::AsRefVar<'_> {}
type AsRefVar<'a> = ();
fn as_ref_var(&self) -> Self::AsRefVar<'_> {}
type AsMutVar<'a> = ();
fn as_mut_var(&mut self) -> Self::AsMutVar<'_> {}
type IterAnyRef<'a>
= std::iter::Empty<&'a dyn Any>
where
Self: 'static;
fn iter_any_ref(&self) -> Self::IterAnyRef<'_>
where
Self: 'static,
{
std::iter::empty()
}
type IterAnyMut<'a>
= std::iter::Empty<&'a mut dyn Any>
where
Self: 'static;
fn iter_any_mut(&mut self) -> Self::IterAnyMut<'_>
where
Self: 'static,
{
std::iter::empty()
}
type IntoOption = ();
fn into_option(self) -> Self::IntoOption {}
type IntoVec = ();
fn into_singleton_vec(self) -> Self::IntoVec {}
}
#[sealed]
pub trait EitherRefVariadic: VariadicExt {
type UnRefVar: VariadicExt;
type RefVar: RefVariadic<UnRefVar = Self::UnRefVar, RefVar = Self::RefVar>;
fn mut_to_ref(self) -> Self::RefVar;
type MutVar: MutVariadic<UnRefVar = Self::UnRefVar, MutVar = Self::MutVar>;
fn unref_ref(&self) -> <Self::UnRefVar as VariadicExt>::AsRefVar<'_>;
}
#[sealed]
impl<'a, Item, Rest> EitherRefVariadic for (&'a Item, Rest)
where
Rest: EitherRefVariadic,
{
type UnRefVar = (Item, Rest::UnRefVar);
type RefVar = (&'a Item, Rest::RefVar);
fn mut_to_ref(self) -> Self::RefVar {
let var_args!(item, ...rest) = self;
var_expr!(item, ...rest.mut_to_ref())
}
type MutVar = (&'a mut Item, Rest::MutVar);
fn unref_ref(&self) -> <Self::UnRefVar as VariadicExt>::AsRefVar<'_> {
let var_args!(item, ...rest) = self;
var_expr!(item, ...rest.unref_ref())
}
}
#[sealed]
impl<'a, Item, Rest> EitherRefVariadic for (&'a mut Item, Rest)
where
Rest: EitherRefVariadic,
{
type UnRefVar = (Item, Rest::UnRefVar);
type RefVar = (&'a Item, Rest::RefVar);
fn mut_to_ref(self) -> Self::RefVar {
let var_args!(item, ...rest) = self;
var_expr!(&*item, ...rest.mut_to_ref())
}
type MutVar = (&'a mut Item, Rest::MutVar);
fn unref_ref(&self) -> <Self::UnRefVar as VariadicExt>::AsRefVar<'_> {
let var_args!(item, ...rest) = self;
var_expr!(item, ...rest.unref_ref())
}
}
#[sealed]
impl EitherRefVariadic for () {
type UnRefVar = ();
type RefVar = ();
fn mut_to_ref(self) -> Self::RefVar {}
type MutVar = ();
fn unref_ref(&self) -> <Self::UnRefVar as VariadicExt>::AsRefVar<'_> {}
}
#[sealed]
pub trait RefVariadic: EitherRefVariadic<RefVar = Self>
where
Self: Copy,
{
}
#[sealed]
impl<Item, Rest> RefVariadic for (&Item, Rest) where Rest: RefVariadic {}
#[sealed]
impl RefVariadic for () {}
#[sealed]
pub trait MutVariadic: EitherRefVariadic<MutVar = Self> {}
#[sealed]
impl<Item, Rest> MutVariadic for (&mut Item, Rest) where Rest: MutVariadic {}
#[sealed]
impl MutVariadic for () {}
#[sealed]
pub trait CopyRefVariadic: EitherRefVariadic {
fn copy_var(&self) -> Self::UnRefVar;
}
#[sealed]
impl<Item, Rest> CopyRefVariadic for (&Item, Rest)
where
Item: Copy,
Rest: CopyRefVariadic,
{
fn copy_var(&self) -> Self::UnRefVar {
let var_args!(&item, ...rest) = self;
var_expr!(item, ...rest.copy_var())
}
}
#[sealed]
impl<Item, Rest> CopyRefVariadic for (&mut Item, Rest)
where
Item: Copy,
Rest: CopyRefVariadic,
{
fn copy_var(&self) -> Self::UnRefVar {
let var_args!(&mut item, ...rest) = self;
var_expr!(item, ...rest.copy_var())
}
}
#[sealed]
impl CopyRefVariadic for () {
fn copy_var(&self) -> Self::UnRefVar {}
}
#[sealed]
pub trait CloneVariadic: VariadicExt + Clone {
fn clone_ref_var(this: Self::AsRefVar<'_>) -> Self;
}
#[sealed]
impl<Item, Rest> CloneVariadic for (Item, Rest)
where
Item: Clone,
Rest: CloneVariadic,
{
fn clone_ref_var(this: Self::AsRefVar<'_>) -> Self {
let var_args!(item, ...rest) = this;
var_expr!(item.clone(), ...Rest::clone_ref_var(rest))
}
}
#[sealed]
impl CloneVariadic for () {
fn clone_ref_var(_this: Self::AsRefVar<'_>) -> Self {}
}
#[sealed]
pub trait PartialEqVariadic: VariadicExt {
fn eq(&self, other: &Self) -> bool;
fn eq_ref(this: Self::AsRefVar<'_>, other: Self::AsRefVar<'_>) -> bool;
}
#[sealed]
impl<Item, Rest> PartialEqVariadic for (Item, Rest)
where
Item: PartialEq,
Rest: PartialEqVariadic,
{
fn eq(&self, other: &Self) -> bool {
let var_args!(item_self, ...rest_self) = self;
let var_args!(item_other, ...rest_other) = other;
item_self == item_other && rest_self.eq(rest_other)
}
fn eq_ref(
this: <Self as VariadicExt>::AsRefVar<'_>,
other: <Self as VariadicExt>::AsRefVar<'_>,
) -> bool {
let var_args!(item_self, ...rest_self) = this;
let var_args!(item_other, ...rest_other) = other;
item_self == item_other && Rest::eq_ref(rest_self, rest_other)
}
}
#[sealed]
impl PartialEqVariadic for () {
fn eq(&self, _other: &Self) -> bool {
true
}
fn eq_ref(
_this: <Self as VariadicExt>::AsRefVar<'_>,
_other: <Self as VariadicExt>::AsRefVar<'_>,
) -> bool {
true
}
}
#[sealed]
pub trait HomogenousVariadic<T>: Variadic {
fn get(&self, i: usize) -> Option<&T>;
fn get_mut(&mut self, i: usize) -> Option<&mut T>;
type IntoIter: Iterator<Item = T>;
fn into_iter(self) -> Self::IntoIter;
}
#[sealed]
impl<T> HomogenousVariadic<T> for () {
fn get(&self, _i: usize) -> Option<&T> {
None
}
fn get_mut(&mut self, _i: usize) -> Option<&mut T> {
None
}
type IntoIter = std::iter::Empty<T>;
fn into_iter(self) -> Self::IntoIter {
std::iter::empty()
}
}
#[sealed]
impl<T, Rest> HomogenousVariadic<T> for (T, Rest)
where
Rest: HomogenousVariadic<T>,
{
fn get(&self, i: usize) -> Option<&T> {
let (item, rest) = self;
if i == 0 {
Some(item)
} else {
rest.get(i - 1)
}
}
fn get_mut(&mut self, i: usize) -> Option<&mut T> {
let (item, rest) = self;
if i == 0 {
Some(item)
} else {
rest.get_mut(i - 1)
}
}
type IntoIter = std::iter::Chain<std::iter::Once<T>, Rest::IntoIter>;
fn into_iter(self) -> Self::IntoIter {
let (item, rest) = self;
std::iter::once(item).chain(rest.into_iter())
}
}
#[sealed]
pub trait Split<Prefix>: VariadicExt
where
Prefix: VariadicExt,
{
type Suffix: VariadicExt;
fn split(self) -> (Prefix, Self::Suffix);
fn split_ref(
this: Self::AsRefVar<'_>,
) -> (
Prefix::AsRefVar<'_>,
<Self::Suffix as VariadicExt>::AsRefVar<'_>,
);
}
#[sealed]
impl<Item, Rest, PrefixRest> Split<(Item, PrefixRest)> for (Item, Rest)
where
PrefixRest: VariadicExt,
Rest: Split<PrefixRest>,
{
type Suffix = <Rest as Split<PrefixRest>>::Suffix;
fn split(self) -> ((Item, PrefixRest), Self::Suffix) {
let (item, rest) = self;
let (prefix_rest, suffix) = rest.split();
((item, prefix_rest), suffix)
}
fn split_ref(
this: Self::AsRefVar<'_>,
) -> (
<(Item, PrefixRest) as VariadicExt>::AsRefVar<'_>,
<Self::Suffix as VariadicExt>::AsRefVar<'_>,
) {
let (item, rest) = this;
let (prefix_rest, suffix) = Rest::split_ref(rest);
((item, prefix_rest), suffix)
}
}
#[sealed]
impl<Rest> Split<var_type!()> for Rest
where
Rest: VariadicExt,
{
type Suffix = Rest;
fn split(self) -> (var_type!(), Self::Suffix) {
(var_expr!(), self)
}
fn split_ref(
this: Self::AsRefVar<'_>,
) -> (var_type!(), <Self::Suffix as VariadicExt>::AsRefVar<'_>) {
(var_expr!(), this)
}
}
#[sealed]
pub trait SplitBySuffix<Suffix>: VariadicExt
where
Suffix: VariadicExt,
{
type Prefix: VariadicExt;
fn split_by_suffix(self) -> (Self::Prefix, Suffix);
fn split_by_suffix_ref(
this: Self::AsRefVar<'_>,
) -> (
<Self::Prefix as VariadicExt>::AsRefVar<'_>,
Suffix::AsRefVar<'_>,
);
}
#[sealed]
impl<Suffix, This> SplitBySuffix<Suffix> for This
where
Suffix: VariadicExt,
This: VariadicExt,
This::Reverse: Split<Suffix::Reverse>,
Suffix::Reverse: VariadicExt<Reverse = Suffix>,
{
type Prefix = <<This::Reverse as Split<Suffix::Reverse>>::Suffix as VariadicExt>::Reverse;
fn split_by_suffix(self) -> (Self::Prefix, Suffix) {
let (rsuffix, rprefix) = self.reverse().split();
(rprefix.reverse(), rsuffix.reverse())
}
fn split_by_suffix_ref(
this: Self::AsRefVar<'_>,
) -> (
<Self::Prefix as VariadicExt>::AsRefVar<'_>,
Suffix::AsRefVar<'_>,
) {
let rev = This::reverse_ref(this);
let (rsuffix, rprefix) = <This::Reverse as Split<Suffix::Reverse>>::split_ref(rev);
let out = (rprefix.reverse(), rsuffix.reverse());
let out2 = unsafe { std::mem::transmute_copy(&out) };
std::mem::forget(out);
out2
}
}
#[sealed]
pub trait VecVariadic: VariadicExt {
type UnVec: VariadicExt<IntoVec = Self>;
fn zip_vecs(&self) -> impl Iterator<Item = <Self::UnVec as VariadicExt>::AsRefVar<'_>>;
fn push(&mut self, item: Self::UnVec);
fn get(&mut self, index: usize) -> Option<<Self::UnVec as VariadicExt>::AsRefVar<'_>>;
type IntoZip: Iterator<Item = Self::UnVec>;
fn into_zip(self) -> Self::IntoZip;
type Drain<'a>: Iterator<Item = Self::UnVec>
where
Self: 'a;
fn drain<R>(&mut self, range: R) -> Self::Drain<'_>
where
R: std::ops::RangeBounds<usize> + Clone;
}
#[sealed]
impl<Item, Rest> VecVariadic for (Vec<Item>, Rest)
where
Rest: VecVariadic,
{
type UnVec = var_type!(Item, ...Rest::UnVec);
fn zip_vecs(&self) -> impl Iterator<Item = <Self::UnVec as VariadicExt>::AsRefVar<'_>> {
let (this, rest) = self;
std::iter::zip(this.iter(), rest.zip_vecs())
}
fn push(&mut self, row: Self::UnVec) {
let (this_vec, rest_vecs) = self;
let (this_col, rest_cols) = row;
this_vec.push(this_col);
rest_vecs.push(rest_cols);
}
fn get(&mut self, index: usize) -> Option<<Self::UnVec as VariadicExt>::AsRefVar<'_>> {
let (this_vec, rest_vecs) = self;
if let Some(rest) = VecVariadic::get(rest_vecs, index) {
this_vec.get(index).map(|item| var_expr!(item, ...rest))
} else {
None
}
}
type IntoZip = std::iter::Zip<std::vec::IntoIter<Item>, Rest::IntoZip>;
fn into_zip(self) -> Self::IntoZip {
let (this, rest) = self;
std::iter::zip(this, rest.into_zip())
}
type Drain<'a>
= std::iter::Zip<std::vec::Drain<'a, Item>, Rest::Drain<'a>>
where
Self: 'a;
fn drain<R>(&mut self, range: R) -> Self::Drain<'_>
where
R: std::ops::RangeBounds<usize> + Clone,
{
let (this, rest) = self;
std::iter::zip(this.drain(range.clone()), rest.drain(range))
}
}
#[sealed]
impl VecVariadic for var_type!() {
type UnVec = var_type!();
fn zip_vecs(&self) -> impl Iterator<Item = <Self::UnVec as VariadicExt>::AsRefVar<'_>> {
std::iter::repeat(var_expr!())
}
fn push(&mut self, _item: Self::UnVec) {}
fn get(&mut self, _index: usize) -> Option<<Self::UnVec as VariadicExt>::AsRefVar<'_>> {
Some(())
}
type IntoZip = std::iter::Repeat<var_type!()>;
fn into_zip(self) -> Self::IntoZip {
std::iter::repeat(var_expr!())
}
type Drain<'a>
= std::iter::Repeat<var_type!()>
where
Self: 'a;
fn drain<R>(&mut self, _range: R) -> Self::Drain<'_>
where
R: std::ops::RangeBounds<usize>,
{
std::iter::repeat(var_expr!())
}
}
#[cfg(test)]
mod test {
use super::*;
type MyList = var_type!(u8, u16, u32, u64);
type MyPrefix = var_type!(u8, u16);
#[expect(dead_code, reason = "compilation test")]
type MySuffix = <MyList as Split<MyPrefix>>::Suffix;
const _: MySuffix = var_expr!(0_u32, 0_u64);
#[test]
fn test_basic_expr() {
let _ = var_expr!();
let _ = var_expr!(1);
let _ = var_expr!(1, "b",);
let _ = var_expr!("a",);
let _ = var_expr!(false, true, 1 + 2);
}
type _ListA = var_type!(u32, u8, i32);
type _ListB = var_type!(..._ListA, bool, Option<()>);
type _ListC = var_type!(..._ListA, bool, Option::<()>);
#[test]
fn test_as_ref_var() {
let my_owned = var_expr!("Hello".to_owned(), Box::new(5));
let my_ref_a = my_owned.as_ref_var();
let my_ref_b = my_owned.as_ref_var();
assert_eq!(my_ref_a, my_ref_b);
}
#[test]
fn test_as_mut_var() {
let mut my_owned = var_expr!("Hello".to_owned(), Box::new(5));
let var_args!(mut_str, mut_box) = my_owned.as_mut_var();
*mut_str += " World";
*mut_box.as_mut() += 1;
assert_eq!(var_expr!("Hello World".to_owned(), Box::new(6)), my_owned);
}
#[test]
fn test_iter_any() {
let mut var = var_expr!(1_i32, false, "Hello".to_owned());
let mut mut_iter = var.iter_any_mut();
*mut_iter.next().unwrap().downcast_mut::<i32>().unwrap() += 1;
*mut_iter.next().unwrap().downcast_mut::<bool>().unwrap() |= true;
*mut_iter.next().unwrap().downcast_mut::<String>().unwrap() += " World";
assert!(mut_iter.next().is_none());
let mut ref_iter = var.iter_any_ref();
assert_eq!(
Some(&2),
ref_iter
.next()
.map(<dyn Any>::downcast_ref)
.map(Option::unwrap)
);
assert_eq!(
Some(&true),
ref_iter
.next()
.map(<dyn Any>::downcast_ref)
.map(Option::unwrap)
);
assert_eq!(
Some("Hello World"),
ref_iter
.next()
.map(|any| &**any.downcast_ref::<String>().unwrap())
);
assert!(ref_iter.next().is_none());
}
#[test]
fn test_homogenous_get() {
let mut var = var_expr!(0, 1, 2, 3, 4);
for i in 0..5 {
assert_eq!(Some(i), var.get(i).copied());
assert_eq!(Some(i), var.get_mut(i).copied());
}
}
#[test]
fn test_into_vec() {
use crate::VecVariadic;
type Item = var_type!(i32, String);
let first: Item = var_expr!(1, "Joe".to_string());
let second: Item = var_expr!(2, "Mingwei".to_string());
let mut column_store = first.clone().into_singleton_vec();
column_store.push(second.clone());
assert_eq!(column_store.len(), 2);
assert_eq!(column_store.get(0).unwrap(), first.as_ref_var());
assert_eq!(column_store.get(1).unwrap(), second.as_ref_var());
}
}
#[test]
fn test_eq_ref_vec() {
type MyVar = var_type!(i32, bool, &'static str);
let vec: Vec<MyVar> = vec![
var_expr!(0, true, "hello"),
var_expr!(1, true, "world"),
var_expr!(2, false, "goodnight"),
var_expr!(3, false, "moon"),
];
let needle: <MyVar as VariadicExt>::AsRefVar<'_> =
var_expr!(2, false, "goodnight").as_ref_var();
assert_eq!(
Some(2),
vec.iter()
.position(|item| <MyVar as PartialEqVariadic>::eq_ref(needle, item.as_ref_var()))
);
let missing: <MyVar as VariadicExt>::AsRefVar<'_> =
var_expr!(3, false, "goodnight").as_ref_var();
assert_eq!(
None,
vec.iter()
.position(|item| <MyVar as PartialEqVariadic>::eq_ref(missing, item.as_ref_var()))
);
}
#[test]
fn clone_var_test() {
let ref_var = var_expr!(&1, &format!("hello {}", "world"), &vec![1, 2, 3]);
let clone_var = CloneVariadic::clone_ref_var(ref_var);
assert_eq!(
var_expr!(1, "hello world".to_owned(), vec![1, 2, 3]),
clone_var
);
}