#[derive(PartialEq, PartialOrd, Eq, Ord, Clone, Copy)]
pub struct QValue(pub(crate) u16);
impl QValue {
pub fn parse(s: &str) -> Option<Self> {
let mut r = byte_reader::Reader::new(s.as_bytes());
match r.consume_oneof(["q=0", "q=1"])? {
0 => {
let mut q = 0;
if r.consume(".").is_some() {
for factor in [100, 10, 1] {
if let Some(b) = r.next_if(u8::is_ascii_digit) {
q += factor * (b - b'0') as u16;
} else {
break;
}
}
}
Some(Self(q))
}
1 => Some(Self(1000)),
_ => unreachable!(),
}
}
pub const fn is_zero(&self) -> bool {
self.0 == 0
}
}
impl Default for QValue {
fn default() -> Self {
Self(1000)
}
}
impl std::fmt::Debug for QValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "q={}", self.0 as f32 / 1000.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_qvalue_parse() {
assert_eq!(QValue::parse("q=0.5"), Some(QValue(500)));
assert_eq!(QValue::parse("q=1"), Some(QValue(1000)));
assert_eq!(QValue::parse("q=0"), Some(QValue(0)));
assert_eq!(QValue::parse("q=0.123"), Some(QValue(123)));
assert_eq!(QValue::parse("q=0.999"), Some(QValue(999)));
assert_eq!(QValue::parse("q=0.000"), Some(QValue(0)));
assert_eq!(QValue::parse("q=1.000"), Some(QValue(1000)));
}
}