pub mod parser; use std::fmt; use std::ops::{Deref, DerefMut}; #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub struct Dice { pub(crate) count: u32, pub(crate) sides: u32, } impl fmt::Display for Dice { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}d{}", self.count, self.sides) } } impl Dice { fn new(count: u32, sides: u32) -> Dice { Dice { count, sides } } } #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum Element { Dice(Dice), Bonus(u32), } impl fmt::Display for Element { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Element::Dice(d) => write!(f, "{}", d), Element::Bonus(b) => write!(f, "{}", b), } } } #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum SignedElement { Positive(Element), Negative(Element), } impl fmt::Display for SignedElement { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { SignedElement::Positive(e) => write!(f, "{}", e), SignedElement::Negative(e) => write!(f, "-{}", e), } } } #[derive(Debug, PartialEq, Eq, Clone)] pub struct ElementExpression(Vec); impl Deref for ElementExpression { type Target = Vec; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for ElementExpression { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl fmt::Display for ElementExpression { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut iter = self.0.iter(); if let Some(first) = iter.next() { write!(f, "{}", first)?; for roll in iter { match roll { SignedElement::Positive(e) => write!(f, " + {}", e)?, SignedElement::Negative(e) => write!(f, " - {}", e)?, } } } Ok(()) } }