Polish the parser

This commit is contained in:
Eunchong Yu 2018-08-19 12:36:16 +09:00
parent c311d37902
commit 8d07c117bb

View file

@ -1,14 +1,13 @@
//! An extension trait that provides the ability to strip IRC colors from a string //! An extension trait that provides the ability to strip IRC colors from a string
use std::borrow::Cow; use std::borrow::Cow;
#[derive(PartialEq)]
enum ParserState { enum ParserState {
Text, Text,
ColorCode, ColorCode,
Foreground1, Foreground1(char),
Foreground2, Foreground2,
Comma, Comma,
Background1, Background1(char),
} }
struct Parser { struct Parser {
state: ParserState, state: ParserState,
@ -49,60 +48,63 @@ impl<'a> FormattedStringExt<'a> for &'a str {
} }
fn strip_formatting(buf: &mut String) { fn strip_formatting(buf: &mut String) {
let mut parser = Parser { let mut parser = Parser::new();
buf.retain(|cur| parser.next(cur));
}
impl Parser {
fn new() -> Self {
Parser {
state: ParserState::Text, state: ParserState::Text,
}; }
let mut prev: char = '\x00'; }
buf.retain(|cur| {
let result = match parser.state { fn next(&mut self, cur: char) -> bool {
ParserState::Text | ParserState::Foreground1 | ParserState::Foreground2 if cur == '\x03' => { use self::ParserState::*;
parser.state = ParserState::ColorCode; match self.state {
Text | Foreground1(_) | Foreground2 if cur == '\x03' => {
self.state = ColorCode;
false false
}, }
ParserState::Text => !FORMAT_CHARACTERS.contains(&cur), Text => {
ParserState::ColorCode if cur.is_digit(10) => { !FORMAT_CHARACTERS.contains(&cur)
parser.state = ParserState::Foreground1; }
ColorCode if cur.is_digit(10) => {
self.state = Foreground1(cur);
false false
}, }
ParserState::Foreground1 if cur.is_digit(6) => { Foreground1('1') if cur.is_digit(6) => {
// can only consume another digit if previous char was 1. // can only consume another digit if previous char was 1.
if prev == '1' { self.state = Foreground2;
parser.state = ParserState::Foreground2;
false false
} else { }
parser.state = ParserState::Text; Foreground1(_) if cur.is_digit(6) => {
self.state = Text;
true true
} }
}, Foreground1(_) if cur == ',' => {
ParserState::Foreground1 if cur == ',' => { self.state = Comma;
parser.state = ParserState::Comma;
false false
},
ParserState::Foreground2 if cur == ',' => {
parser.state = ParserState::Comma;
false
},
ParserState::Comma if (cur.is_digit(10)) => {
parser.state = ParserState::Background1;
false
},
ParserState::Background1 if cur.is_digit(6) => {
// can only consume another digit if previous char was 1.
parser.state = ParserState::Text;
if prev == '1' {
false
} else {
true
} }
Foreground2 if cur == ',' => {
self.state = Comma;
false
}
Comma if (cur.is_digit(10)) => {
self.state = Background1(cur);
false
}
Background1(prev) if cur.is_digit(6) => {
// can only consume another digit if previous char was 1.
self.state = Text;
prev != '1'
} }
_ => { _ => {
parser.state = ParserState::Text; self.state = Text;
true true
} }
}; }
prev = cur; }
return result
});
} }
impl FormattedStringExt<'static> for String { impl FormattedStringExt<'static> for String {