use std::cmp::Ordering;
use std::fmt;
use parse::*;
use pest::*;
pub fn roll_dice(r: &str) -> i64 {
let parser = RollParser::parse(Rule::calc, r);
compute(parser.expect("Failed to parse roll!"))
}
pub fn roll_dice_or_fail(r: &str) -> Result<i64, Error<impl RuleType>> {
let parser = RollParser::parse(Rule::calc, r);
parser.map(compute)
}
pub fn roller_or_fail<'a>(r: &'a str) -> Result<Roller<'a>, Error<impl RuleType>> {
let parser = RollParser::parse(Rule::calc, r);
parser.map(|p| {
Roller {
roll: r,
total: compute(p),
}
})
}
#[derive(Debug, Clone, Copy)]
pub struct Roller<'a> {
roll: &'a str,
total: i64,
}
impl<'a> Roller<'a> {
pub fn new(roll: &'a str) -> Self {
Roller {
roll,
total: roll_dice(roll),
}
}
pub fn reroll(&mut self) -> i64 {
self.total = roll_dice(self.roll);
self.total
}
pub fn total(&self) -> i64 {
self.total
}
pub fn iter(&mut self) -> &mut Self {
self.by_ref()
}
}
impl<'a> Iterator for Roller<'a> {
type Item = i64;
fn next(&mut self) -> Option<i64> {
Some(self.reroll())
}
}
impl<'a> PartialEq for Roller<'a> {
fn eq(&self, other: &Roller) -> bool {
self.total == other.total
}
}
impl<'a> Eq for Roller<'a> {}
impl<'a> Ord for Roller<'a> {
fn cmp(&self, other: &Roller) -> Ordering {
self.total.cmp(&other.total)
}
}
impl<'a> PartialOrd for Roller<'a> {
fn partial_cmp(&self, other: &Roller) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<'a> fmt::Display for Roller<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}: {}]", self.roll, self.total)
}
}