Skip to content

Instantly share code, notes, and snippets.

@aflaag
Last active August 28, 2021 13:45
Show Gist options
  • Save aflaag/e0f7055c9bade6b4a6ac8cf70fc16bfb to your computer and use it in GitHub Desktop.
Save aflaag/e0f7055c9bade6b4a6ac8cf70fc16bfb to your computer and use it in GitHub Desktop.
finally i managed to do this
use std::{fmt, marker::PhantomData};
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
pub enum Value {
Zero,
One,
BitNumber,
}
impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
macro_rules! information_methods {
($strct:ident, $func:ident) => {
fn $func(&self) -> $strct<Self> where Self: Sized + Copy {
$strct(*self)
}
};
}
pub trait Information {
information_methods!(Zero, zero);
information_methods!(One, one);
fn inner(&self) -> Option<&dyn Information>;
fn value(&self) -> Value;
}
impl fmt::Display for &dyn Information {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", match self.value() {
Value::Zero => "0",
Value::One => "1",
Value::BitNumber => "",
})
}
}
macro_rules! impl_information {
($strct:ident, $inner:expr, $self:ident $(, $generic:ident)?) => {
impl$(<$generic: Information>)? Information for $strct$(<$generic>)? {
fn inner(&$self) -> Option<&dyn Information> {
$inner
}
fn value(&self) -> Value {
Value::$strct
}
}
};
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
pub struct BitNumber;
impl BitNumber {
pub fn new() -> Self {
Self
}
}
impl_information!(BitNumber, None, self);
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
pub struct Zero<B: Information>(B);
impl_information!(Zero, Some(&self.0), self, B);
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
pub struct One<B: Information>(B);
impl_information!(One, Some(&self.0), self, B);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Number<'n, B: Information> {
bits: &'n B,
}
impl<'n, B: Information> Number<'n, B> {
pub fn iter(&self) -> NumberIter<'n, B> {
NumberIter {
curr: Some(self.bits),
_marker: PhantomData,
}
}
}
impl<'n, B: Information> From<&'n B> for Number<'n, B> {
fn from(bits: &'n B) -> Self {
Self { bits }
}
}
impl<'n, B: Information> IntoIterator for Number<'n, B> {
type Item = &'n dyn Information;
type IntoIter = NumberIter<'n, B>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
#[derive(Clone, Copy)]
pub struct NumberIter<'n, B: Information> {
curr: Option<&'n dyn Information>,
_marker: PhantomData<B>,
}
impl<'n, B: Information> Iterator for NumberIter<'n, B> {
type Item = &'n dyn Information;
fn next(&mut self) -> Option<Self::Item> {
if let Some(curr) = self.curr {
self.curr = curr.inner();
Some(curr)
} else {
None
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment