#[macro_export]
macro_rules! derive_primitive {
($type:ty) => {
impl Quine for $type {
fn ctor_tokens(&self) -> TokenStream {
self.to_token_stream()
}
}
};
($type:ty, $($rest:ty),*) => {
derive_primitive!($type);
derive_primitive!($($rest),*);
};
}
#[macro_export]
macro_rules! derive_iterable {
($(::)? $($pth:ident)::+ $type:ident < $($param:ident),* >) => {
impl<$($param: Quine),*> Quine for ($($pth)::* $type)<$($param),*> {
fn ctor_tokens(&self) -> TokenStream {
let inner = self
.iter()
.map(|item| item.ctor_tokens())
.collect::<Vec<_>>();
quote! {
$($pth)::* $type::from([#(#inner),*])
}
}
}
};
($type:ident < $($param:ident),* >) => {
impl<$($param: Quine),*> Quine for $type<$($param),*> {
fn ctor_tokens(&self) -> TokenStream {
let inner = self
.iter()
.map(|item| item.ctor_tokens())
.collect::<Vec<_>>();
quote! {
$type::from([#(#inner),*])
}
}
}
};
($type:ident) => {
impl Quine for $type {
fn ctor_tokens(&self) -> TokenStream {
let inner = self
.iter()
.map(|item| item.ctor_tokens())
.collect::<Vec<_>>();
quote! {
$type::from([#(#inner),*])
}
}
}
};
}
#[macro_export]
macro_rules! derive_tuple {
( $( $name:ident )+ ) => {
impl<$($name: Quine),*> Quine for ($($name,)*)
{
fn ctor_tokens(&self) -> TokenStream {
#[allow(non_snake_case)]
let ($($name,)*) = self;
let ctors = vec![$($name.ctor_tokens()),*];
quote! {
(#(#ctors),*)
}
}
}
};
}
#[macro_export]
macro_rules! derive_tuple_all {
( $one:ident ) => {
derive_tuple!($one);
};
( $head:ident $($rest:ident)* ) => {
derive_tuple!($head $($rest)*);
derive_tuple_all!($($rest)*);
};
}
#[macro_export]
macro_rules! derive_trivial {
($type:ty) => {
impl Quine for $type {
fn ctor_tokens(&self) -> TokenStream {
quote! {
$type::from(#self)
}
}
}
};
($type:ty, $($rest:ty),*) => {
derive_trivial!($type);
derive_trivial!($($rest),*);
}
}