macro_rules! parse_error {
( $line: expr, $kind: ident ) => {
Err($crate::error::Error::Parse(
$crate::error::ParseError::$kind,
$line,
))
};
( $line: expr, $kind: ident, $( $value: expr )* ) => {
Err($crate::error::Error::Parse(
$crate::error::ParseError::$kind(
$( $value )*
),
$line,
))
};
}
mod minify;
mod parse;
mod replace;
mod statements;
use std::collections::HashMap;
use fancy_regex::Regex;
pub(crate) use self::replace::replace_classes;
use self::minify::minify;
use crate::{error::Error, outcome::Outcome};
pub(crate) type Classes = HashMap<String, (String, usize)>;
#[derive(Debug, PartialEq)]
pub struct Draft {
pub rules: Vec<Rule>,
pub messages: Vec<Message<TestDraft>>,
pub name: Option<String>,
pub mode: Mode,
pub test_count: usize,
pub(crate) raw_rules: Vec<RawRule>,
pub(crate) raw_classes: Classes,
}
#[derive(Debug, Clone)]
pub struct Rule {
pub pattern: Regex,
pub intent: bool,
pub note: Option<Note>,
}
#[derive(Debug, PartialEq)]
pub(crate) struct RawRule {
pub pattern: String,
pub intent: bool,
pub note: Option<Note>,
pub line: usize,
}
#[derive(Debug, PartialEq)]
pub enum Message<T> {
Info(Note),
Test(T),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Note(pub String);
#[derive(Debug, PartialEq, Clone)]
pub struct TestDraft {
pub word: String,
pub intent: bool,
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Mode {
Romanized,
Broad,
Narrow,
}
impl Draft {
pub fn run(&self) -> Outcome {
Outcome::run(self)
}
pub fn minify(&self, with_tests: bool) -> Result<String, Error> {
minify(
self.mode,
&self.raw_classes,
&self.raw_rules,
&self.messages,
with_tests,
)
}
}
impl PartialEq for Rule {
fn eq(&self, other: &Self) -> bool {
self.intent == other.intent
&& self.note == other.note
&& self.pattern.to_string() == other.pattern.to_string()
}
}
impl<T> Message<T> {
pub fn is_note(&self) -> bool {
matches!(self, Self::Info(_))
}
pub fn is_test(&self) -> bool {
matches!(self, Self::Test(_))
}
}
impl Default for Mode {
fn default() -> Self {
Self::Romanized
}
}
impl Mode {
pub fn from(first: char, last: char) -> Option<Self> {
use Mode::*;
Some(match (first, last) {
('<', '>') => Romanized,
('/', '/') => Broad,
('[', ']') => Narrow,
_ => return None,
})
}
pub fn from_options(first: Option<char>, last: Option<char>) -> Option<Self> {
match (first, last) {
(Some(a), Some(b)) => Self::from(a, b),
_ => None,
}
}
pub fn as_str(self) -> &'static str {
use Mode::*;
match self {
Romanized => "<>",
Broad => "//",
Narrow => "[]",
}
}
}