#[derive(Debug, Copy, Clone)]
pub struct IsPublic;
#[derive(Debug, Copy, Clone)]
pub struct IsPrivate;
mod sealed {
use super::{IsPrivate, IsPublic};
pub trait Sealed {}
impl Sealed for IsPublic {}
impl Sealed for IsPrivate {}
}
use self::sealed::Sealed;
pub trait Privacy: Sealed {}
impl Privacy for IsPublic {}
impl Privacy for IsPrivate {}
pub type CombinePrivacyOut<Lhs, Rhs> = <Lhs as CombinePrivacy<Rhs>>::Output;
pub trait CombinePrivacy<Rhs: Privacy> {
type Output: Privacy;
}
impl<A: Privacy> CombinePrivacy<A> for IsPublic {
type Output = A;
}
impl<A: Privacy> CombinePrivacy<A> for IsPrivate {
type Output = IsPrivate;
}
macro_rules! tuple_impls {
(small=> $ty:ty = $output:ty) => {
impl<Carry: Privacy> CombinePrivacy<Carry> for $ty {
type Output = $output;
}
};
(large=>
$( ($t0:ident,$t1:ident,$t2:ident,$t3:ident,), )*
$($trailing:ident,)*
)=>{
#[allow(non_camel_case_types)]
impl<A: Privacy, $($t0,$t1,$t2,$t3,)* $($trailing,)* CombTuples >
CombinePrivacy<A>
for ($($t0,$t1,$t2,$t3,)* $($trailing,)*)
where
($($trailing,)*): CombinePrivacy<A>,
$( ($t0,$t1,$t2,$t3): CombinePrivacy<IsPublic>, )*
(
$( CombinePrivacyOut<($t0,$t1,$t2,$t3), IsPublic>, )*
):CombinePrivacy<
CombinePrivacyOut<($($trailing,)*), A>,
Output = CombTuples,
>,
CombTuples: Privacy,
{
type Output = CombTuples;
}
};
}
impl_all_trait_for_tuples! {
macro = tuple_impls,
true = IsPublic,
false = IsPrivate,
}