From 21a535e8f1fba785e3176a83c4f7a6d4e48d2eda Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 29 Jul 2020 04:05:30 +0100 Subject: [PATCH] documented --- src/interval.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/src/interval.rs b/src/interval.rs index 51fef07..324c8b5 100644 --- a/src/interval.rs +++ b/src/interval.rs @@ -1,3 +1,5 @@ +//! Parsing times from definition files + use std::{ str, num::{self, NonZeroU64}, @@ -24,7 +26,7 @@ impl Unit { /// Multiplier to get to miliseconds #[inline] - pub const fn multiplier(&self) -> u64 { + const fn multiplier(&self) -> u64 { use Unit::*; match self { Second => 1000, @@ -38,11 +40,13 @@ impl Unit } } +/// A time object parsed from the definition file. #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord,PartialOrd)] pub struct Time { unit: Unit, value: NonZeroU64, + /// Value in miliseconds absolute: Option, } @@ -110,11 +114,17 @@ impl Time impl Time { - pub fn extend(self, other: Self) -> Result + /// Get the absolute value of the interval in miliseconds + pub fn ms(&self) -> u64 + { + self.absolute.unwrap().into() + } + + fn extend(self, other: Self) -> Result { Ok(Self::try_from_ms(unsafe{NonZeroU64::new_unchecked(u64::from(self.absolute.unwrap()) + u64::from(other.absolute.unwrap()))})?) } - pub fn parse_chars(from: &mut I) -> Result + fn parse_chars(from: &mut I) -> Result where I: Iterator { let mut token = String::new(); @@ -135,7 +145,7 @@ impl Time 'd' | 'D' => Some(Unit::Day), 'w' | 'W' => Some(Unit::Week), 'y' | 'Y' => Some(Unit::Year), - 'A' => Some(Unit::Aeon), + '∞' => Some(Unit::Aeon), white if white.is_whitespace() => continue, _ => return Err(ParseError::UnexpectedToken(tok, i)), }; @@ -197,12 +207,54 @@ pub fn parse_many_into(string: impl AsRef) -> Result }).unwrap_or(Err(ParseErrorMany{error: ParseError::Empty, line:0})) } + +impl std::fmt::Display for Unit +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + use Unit::*; + write!(f, "{}", match self { + Second => 's', + Minute => 'm', + Hour => 'h', + Day => 'd', + Week => 'w', + Year => 'y', + Aeon => '∞', + }) + } +} + +impl std::fmt::Display for Time +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + write!(f, "{} {}", self.value, self.unit) + } +} + +/// Shows which atom parse error originated #[derive(Debug)] pub struct ParseErrorMany { error: ParseError, line: usize, } -impl std::error::Error for ParseErrorMany{} +impl ParseErrorMany +{ + /// The atom number that error originated + pub fn atom(&self) -> usize + { + self.line + } +} +impl std::error::Error for ParseErrorMany +{ + /// The `ParseError` source of this error + fn source(&self) -> Option<&(dyn std::error::Error +'static)> + { + Some(&self.error) + } +} impl std::fmt::Display for ParseErrorMany { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result @@ -217,6 +269,7 @@ type IntErrorKind = std::num::IntErrorKind; #[cfg(not(nightly))] type IntErrorKind = (); +/// Error in parsing `Time` #[derive(Debug)] pub enum ParseError { Empty, @@ -267,7 +320,7 @@ mod tests #[test] fn parse_single() { - let time: Time = "100A".parse().expect("parse failed"); + let time: Time = "100∞".parse().expect("parse failed"); assert_eq!(time, Time::new(NonZeroU64::try_from(100).unwrap(), Unit::Aeon)); }