relex 1.0.0

a library for building a regex-based lexer
Documentation
use crate::*;
use regex::Regex;
use std::fmt::Debug;

fn mk_prefixed_re<S: AsRef<str>>(re: S) -> Result<regex::Regex, regex::Error> {
  let mut re = re.as_ref().to_string();
  if !re.starts_with('^') {
    re = "^".to_string() + &re;
  }
  Regex::new(&re)
}

/// Represents a lexer rule: i.e., a regex that can produce tokens, and whether they are skippable
/// or not. A Rule also stores the token kind.
#[derive(Debug, Clone)]
pub struct Rule<K: TokenKind> {
  pub kind: K,
  pub re: Regex,
  pub skip: bool,
  pub capture: bool,
}
impl<K: TokenKind> Rule<K> {
  pub fn new(kind: K, re: &str) -> Result<Self, regex::Error> {
    Ok(Rule {
      kind,
      re: mk_prefixed_re(re)?,
      skip: false,
      capture: false,
    })
  }

  /// set whether tokens generated from this rule should capture groups from the regex
  pub fn capture(mut self, capture: bool) -> Self {
    self.capture = capture;
    self
  }

  /// set whether this token should be skipped
  pub fn skip(mut self, skip: bool) -> Self {
    self.skip = skip;
    self
  }
}

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

  #[test]
  fn test_new() {
    let r: Rule<_> = Rule::new("XYZ", "xyz").unwrap();
    assert_eq!(r.kind, "XYZ");
    assert_eq!(r.re.as_str(), "^xyz");
    assert_eq!(r.skip, false);
  }
}