Reduce allocation more
String::strip_formatting will do most of operations in place.
This commit is contained in:
parent
4feafc681a
commit
b108c833bb
1 changed files with 60 additions and 63 deletions
|
@ -39,82 +39,79 @@ impl<'a> FormattedStringExt<'a> for &'a str {
|
||||||
if !self.is_formatted() {
|
if !self.is_formatted() {
|
||||||
return Cow::Borrowed(self);
|
return Cow::Borrowed(self);
|
||||||
}
|
}
|
||||||
Cow::Owned(internal::strip_formatting(self))
|
let mut s = String::from(self);
|
||||||
|
strip_formatting(&mut s);
|
||||||
|
Cow::Owned(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod internal { // to reduce commit diff
|
fn strip_formatting(buf: &mut String) {
|
||||||
use super::*;
|
let mut parser = Parser {
|
||||||
pub(super) fn strip_formatting(input: &str) -> String {
|
state: ParserState::Text,
|
||||||
let mut parser = Parser {
|
};
|
||||||
state: ParserState::Text,
|
let mut prev: char = '\x00';
|
||||||
|
buf.retain(|cur| {
|
||||||
|
let result = match parser.state {
|
||||||
|
ParserState::Text | ParserState::Foreground1 | ParserState::Foreground2 if cur == '\x03' => {
|
||||||
|
parser.state = ParserState::ColorCode;
|
||||||
|
false
|
||||||
|
},
|
||||||
|
ParserState::Text => !['\x02', '\x1F', '\x16', '\x0F'].contains(&cur),
|
||||||
|
ParserState::ColorCode if cur.is_digit(10) => {
|
||||||
|
parser.state = ParserState::Foreground1;
|
||||||
|
false
|
||||||
|
},
|
||||||
|
ParserState::Foreground1 if cur.is_digit(6) => {
|
||||||
|
// can only consume another digit if previous char was 1.
|
||||||
|
if prev == '1' {
|
||||||
|
parser.state = ParserState::Foreground2;
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
parser.state = ParserState::Text;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ParserState::Foreground1 if cur == ',' => {
|
||||||
|
parser.state = ParserState::Comma;
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
parser.state = ParserState::Text;
|
||||||
|
true
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let mut prev: char = '\x00';
|
prev = cur;
|
||||||
input
|
return result
|
||||||
.chars()
|
});
|
||||||
.filter(move |cur| {
|
|
||||||
let result = match parser.state {
|
|
||||||
ParserState::Text | ParserState::Foreground1 | ParserState::Foreground2 if *cur == '\x03' => {
|
|
||||||
parser.state = ParserState::ColorCode;
|
|
||||||
false
|
|
||||||
},
|
|
||||||
ParserState::Text => !['\x02', '\x1F', '\x16', '\x0F'].contains(cur),
|
|
||||||
ParserState::ColorCode if (*cur).is_digit(10) => {
|
|
||||||
parser.state = ParserState::Foreground1;
|
|
||||||
false
|
|
||||||
},
|
|
||||||
ParserState::Foreground1 if (*cur).is_digit(6) => {
|
|
||||||
// can only consume another digit if previous char was 1.
|
|
||||||
if (prev) == '1' {
|
|
||||||
parser.state = ParserState::Foreground2;
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
parser.state = ParserState::Text;
|
|
||||||
true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ParserState::Foreground1 if *cur == ',' => {
|
|
||||||
parser.state = ParserState::Comma;
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
parser.state = ParserState::Text;
|
|
||||||
true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
prev = *cur;
|
|
||||||
return result
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormattedStringExt<'static> for String {
|
impl FormattedStringExt<'static> for String {
|
||||||
fn is_formatted(&self) -> bool {
|
fn is_formatted(&self) -> bool {
|
||||||
self.as_str().is_formatted()
|
self.as_str().is_formatted()
|
||||||
}
|
}
|
||||||
fn strip_formatting(self) -> Cow<'static, str> {
|
fn strip_formatting(mut self) -> Cow<'static, str> {
|
||||||
if !self.is_formatted() {
|
if !self.is_formatted() {
|
||||||
return Cow::Owned(self);
|
return Cow::Owned(self);
|
||||||
}
|
}
|
||||||
Cow::Owned(internal::strip_formatting(&self))
|
strip_formatting(&mut self);
|
||||||
|
Cow::Owned(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue