djr 0.0.1

Djot parser written in pure Rust
Documentation
use phf::phf_map;

static ROMAN_DIGITS: phf::Map<u8, usize> = phf_map! {
    b'i' => 1,
    b'v' => 5,
    b'x' => 10,
    b'l' => 50,
    b'c' => 100,
    b'd' => 500,
    b'm' => 1000,
};

pub(crate) fn _roman_to_number(text: &str) -> Option<usize> {
    let mut total = 0;
    let mut prev_digit = 0;

    for byte in text.to_lowercase().bytes().rev() {
        match ROMAN_DIGITS.get(&byte) {
            Some(&n) => {
                if n < prev_digit {
                    total -= n;
                } else {
                    total += n;
                }
                prev_digit = n;
            }
            None => return None,
        }
    }

    Some(total)
}

#[inline]
pub(crate) fn is_roman(c: u8) -> bool {
    matches!(
        c.to_ascii_lowercase(),
        b'i' | b'v' | b'x' | b'l' | b'c' | b'd' | b'm'
    )
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn parses_roman_numerals() {
        let examples = vec![
            ("MMXXII", Some(2022)),
            ("ix", Some(9)),
            ("wrong", None),
            ("McmXiI", Some(1912)),
        ];

        for (example, want) in examples {
            let got = roman_to_number(example);
            assert_eq!(want, got);
        }
    }
}