Merge pull request #133 from freddyb/add-formattedstring

add support for formatted strings (fixes #130)
This commit is contained in:
Aaron Weiss 2018-04-15 22:41:59 +02:00 committed by GitHub
commit 4fe5862632
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 133 additions and 0 deletions

131
src/proto/colors.rs Normal file
View file

@ -0,0 +1,131 @@
//! An extension trait that provides the ability to strip IRC colors from a string
use std::borrow::Cow;
#[derive(PartialEq)]
enum ParserState {
Text,
ColorCode,
Foreground1,
Foreground2,
Comma,
Background1,
}
struct Parser {
state: ParserState,
}
/// An extension trait giving strings a function to strip IRC colors
pub trait FormattedStringExt {
/// Returns true if the string contains color, bold, underline or italics
fn is_formatted(&self) -> bool;
/// Returns the string with all color, bold, underline and italics stripped
fn strip_formatting(&self) -> Cow<str>;
}
impl FormattedStringExt for str {
fn is_formatted(&self) -> bool {
self.contains('\x02') || // bold
self.contains('\x1F') || // underline
self.contains('\x16') || // reverse
self.contains('\x0F') || // normal
self.contains('\x03') // color
}
fn strip_formatting(&self) -> Cow<str> {
let mut parser = Parser {
state: ParserState::Text,
};
let result: Cow<str> = self
.chars()
.filter(move |cur| {
match parser.state {
ParserState::Text 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) => {
parser.state = ParserState::Foreground2;
false
},
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) => {
parser.state = ParserState::Text;
false
}
_ => true
}
})
.collect();
result
}
}
impl FormattedStringExt for String {
fn is_formatted(&self) -> bool {
(&self[..]).is_formatted()
}
fn strip_formatting(&self) -> Cow<str> {
(&self[..]).strip_formatting()
}
}
#[cfg(test)]
mod test {
use proto::colors::FormattedStringExt;
#[test]
fn test_strip_bold() {
assert_eq!("l\x02ol".strip_formatting(), "lol");
}
#[test]
fn test_strip_fg_color() {
assert_eq!("l\x033ol".strip_formatting(), "lol");
}
#[test]
fn test_strip_fg_color2() {
assert_eq!("l\x0312ol".strip_formatting(), "lol");
}
#[test]
fn test_strip_fg_bg_11() {
assert_eq!("l\x031,2ol".strip_formatting(), "lol");
}
#[test]
fn test_strip_fg_bg_21() {
assert_eq!("l\x0312,3ol".strip_formatting(), "lol");
}
#[test]
fn test_strip_fg_bg_12() {
assert_eq!("l\x031,12ol".strip_formatting(), "lol");
}
#[test]
fn test_strip_fg_bg_22() {
assert_eq!("l\x0312,13ol".strip_formatting(), "lol");
}
}

View file

@ -3,6 +3,7 @@
pub mod caps;
pub mod chan;
pub mod command;
pub mod colors;
pub mod irc;
pub mod line;
pub mod message;
@ -11,6 +12,7 @@ pub mod response;
pub use self::caps::{Capability, NegotiationVersion};
pub use self::chan::ChannelExt;
pub use self::colors::FormattedStringExt;
pub use self::command::{BatchSubCommand, CapSubCommand, Command};
pub use self::irc::IrcCodec;
pub use self::message::Message;