// Copyright (c) 2016-2021 Fabian Schuiki use moore_common::errors::DiagBuilder2; use moore_common::grind::Grinder; /// A grinder that categorizes characters into different groups as per the VHDL /// language standard. pub struct Categorizer { inner: T, } impl Categorizer where T: Grinder, Error = DiagBuilder2>, { /// Create a new categorizer. pub fn new(inner: T) -> Categorizer { Categorizer { inner: inner } } } impl Grinder for Categorizer where T: Grinder, Error = DiagBuilder2>, { type Item = Option<(usize, char, u8, Category)>; type Error = DiagBuilder2; fn emit(&mut self, err: Self::Error) { self.inner.emit(err); } fn next(&mut self) -> Self::Item { let (offset, c, sz) = match self.inner.next() { Some(v) => v, None => return None, }; let cat = match c { '"' | '#' | '&' | '\'' | '(' | ')' | '*' | '+' | ',' | '-' | '.' | '/' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | '[' | ']' | '_' | '`' | '|' => Category::Special, c if c.is_alphabetic() => Category::Letter, c if c.is_digit(10) => Category::Digit, c if c.is_whitespace() => Category::Space, _ => Category::Other, }; Some((offset, c, sz, cat)) } } /// A character category. Special means the special characters as defined by the /// VHDL standard to be meaningful syntactically. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum Category { Letter, Digit, Special, Space, Other, }