add support for formatted strings (fixes #130)

This commit is contained in:
Frederik B 2018-03-31 21:18:23 +02:00
parent cba63a80c6
commit 654b759c02
2 changed files with 96 additions and 0 deletions

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

@ -0,0 +1,94 @@
//! 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()
}
}

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;