pub trait Repr {
type Ref<'a>: Repr
where
Self: 'a;
type Mut<'a>: Repr
where
Self: 'a;
fn as_ref(&self) -> Self::Ref<'_>;
fn as_mut_ref(&mut self) -> Self::Mut<'_>;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Zero {}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Sum<T, R> {
This(T),
Next(R),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct One;
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Product<T, R>(pub T, pub R);
impl Repr for Zero {
type Ref<'a> = Zero;
type Mut<'a> = Zero;
fn as_ref(&self) -> Self::Ref<'_> {
match *self {}
}
fn as_mut_ref(&mut self) -> Self::Mut<'_> {
match *self {}
}
}
impl Repr for One {
type Ref<'a> = One;
type Mut<'a> = One;
fn as_ref(&self) -> Self::Ref<'_> {
One
}
fn as_mut_ref(&mut self) -> Self::Mut<'_> {
One
}
}
impl<T: Repr, R: Repr> Repr for Sum<T, R> {
type Ref<'a> = Sum<T::Ref<'a>, R::Ref<'a>>
where T: 'a, R: 'a;
type Mut<'a> = Sum<T::Mut<'a>, R::Mut<'a>>
where T: 'a, R: 'a;
fn as_ref(&self) -> Self::Ref<'_> {
match self {
Sum::This(x) => Sum::This(x.as_ref()),
Sum::Next(x) => Sum::Next(x.as_ref()),
}
}
fn as_mut_ref(&mut self) -> Self::Mut<'_> {
match self {
Sum::This(x) => Sum::This(x.as_mut_ref()),
Sum::Next(x) => Sum::Next(x.as_mut_ref()),
}
}
}
impl<T, R: Repr> Repr for Product<T, R> {
type Ref<'a> = Product<&'a T, R::Ref<'a>>
where T: 'a, R: 'a;
type Mut<'a> = Product<&'a mut T, R::Mut<'a>>
where T: 'a, R: 'a;
fn as_ref(&self) -> Self::Ref<'_> {
Product(&self.0, self.1.as_ref())
}
fn as_mut_ref(&mut self) -> Self::Mut<'_> {
Product(&mut self.0, self.1.as_mut_ref())
}
}
pub trait Generic {
type Repr: Repr;
fn into_repr(self) -> Self::Repr;
fn from_repr(repr: Self::Repr) -> Self;
fn as_repr(&self) -> <Self::Repr as Repr>::Ref<'_>;
fn as_mut_repr(&mut self) -> <Self::Repr as Repr>::Mut<'_>;
}