From e731144025b726670cd85d43acdd93b7636de338 Mon Sep 17 00:00:00 2001 From: Max Audron Date: Tue, 19 Oct 2021 14:03:17 +0200 Subject: add formatting trait for irc codes add an impl off the formatting trait on String to format Strings with the typical irc formatting codes for bold, italic etc --- src/util/formatting.rs | 50 ----------------------- src/util/formatting/color.rs | 41 +++++++++++++++++++ src/util/formatting/mod.rs | 88 +++++++++++++++++++++++++++++++++++++++++ src/util/formatting/truncate.rs | 50 +++++++++++++++++++++++ 4 files changed, 179 insertions(+), 50 deletions(-) delete mode 100644 src/util/formatting.rs create mode 100644 src/util/formatting/color.rs create mode 100644 src/util/formatting/mod.rs create mode 100644 src/util/formatting/truncate.rs (limited to 'src/util') diff --git a/src/util/formatting.rs b/src/util/formatting.rs deleted file mode 100644 index c1b6257..0000000 --- a/src/util/formatting.rs +++ /dev/null @@ -1,50 +0,0 @@ -/// Truncates a string after a certain number of characters. -/// Function always tries to truncate on a word boundary. -/// Reimplemented from gonzobot. -pub fn truncate(text: &str, len: usize) -> String { - if text.len() <= len { - return text.to_string(); - } - format!( - "{}…", - text[..len] - .rsplitn(2, " ") - .collect::>() - .last() - .copied() - .expect("This can never happen >inb4 it happens") - ) -} - -#[cfg(test)] -mod tests { - use super::truncate; - - #[test] - fn test_truncate_with_input_of_lesser_length_than_limit() { - let input = "short text"; - let result = truncate(input, input.len() + 1); - assert_eq!(input, result) - } - - #[test] - fn test_truncate_with_input_of_equal_length_as_limit() { - let input = "short text"; - let result = truncate(input, input.len()); - assert_eq!(input, result) - } - - #[test] - fn test_truncate_with_input_of_greater_length_than_limit() { - let input = "some longer text"; - let result = truncate(input, input.len() - 1); - assert_eq!("some longer…", result) - } - - #[test] - fn test_truncate_with_input_of_greater_length_than_limit_oneword() { - let input = "somelongertext"; - let result = truncate(input, input.len() - 1); - assert_eq!("somelongertex…", result) - } -} diff --git a/src/util/formatting/color.rs b/src/util/formatting/color.rs new file mode 100644 index 0000000..6907805 --- /dev/null +++ b/src/util/formatting/color.rs @@ -0,0 +1,41 @@ +pub enum Color { + White = 00, + Black = 01, + Blue = 02, + Green = 03, + Red = 04, + Brown = 05, + Magenta = 06, + Orange = 07, + Yellow = 08, + LightGreen = 09, + Cyan = 10, + LightCyan = 11, + LightBlue = 12, + Pink = 13, + Grey = 14, + LightGrey = 15, +} + +impl std::fmt::Display for Color { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Color::White => f.write_str("\x00"), + Color::Black => f.write_str("\x01"), + Color::Blue => f.write_str("\x02"), + Color::Green => f.write_str("\x03"), + Color::Red => f.write_str("\x04"), + Color::Brown => f.write_str("\x05"), + Color::Magenta => f.write_str("\x06"), + Color::Orange => f.write_str("\x07"), + Color::Yellow => f.write_str("\x08"), + Color::LightGreen => f.write_str("\x09"), + Color::Cyan => f.write_str("\x10"), + Color::LightCyan => f.write_str("\x11"), + Color::LightBlue => f.write_str("\x12"), + Color::Pink => f.write_str("\x13"), + Color::Grey => f.write_str("\x14"), + Color::LightGrey => f.write_str("\x15"), + } + } +} diff --git a/src/util/formatting/mod.rs b/src/util/formatting/mod.rs new file mode 100644 index 0000000..5cfdfa8 --- /dev/null +++ b/src/util/formatting/mod.rs @@ -0,0 +1,88 @@ +mod truncate; +mod color; + +pub use truncate::*; +pub use color::*; + +pub trait Formatting<'r> { + const BOLD: &'r str = "\x02"; + const ITALIC: &'r str = "\x1D"; + const UNDERLINE: &'r str = "\x1F"; + const STRIKETHROUGH: &'r str = "\x1E"; + const MONOSPACE: &'r str = "\x11"; + const COLOR: &'r str = "\x03"; + + fn bold(self) -> Self; + fn italic(self) -> Self; + fn underline(self) -> Self; + fn strikethrough(self) -> Self; + fn monospace(self) -> Self; + // fn color(self, color: Color) -> Self; +} + +impl<'r> Formatting<'r> for String { + fn bold(mut self) -> Self { + self.insert_str(0, Self::BOLD); + self.push_str(Self::BOLD); + + return self; + } + + fn italic(mut self) -> Self { + self.insert_str(0, Self::ITALIC); + self.push_str(Self::ITALIC); + + return self; + } + + fn underline(mut self) -> Self { + self.insert_str(0, Self::UNDERLINE); + self.push_str(Self::UNDERLINE); + + return self; + } + + fn strikethrough(mut self) -> Self { + self.insert_str(0, Self::STRIKETHROUGH); + self.push_str(Self::STRIKETHROUGH); + + return self; + } + + fn monospace(mut self) -> Self { + self.insert_str(0, Self::MONOSPACE); + self.push_str(Self::MONOSPACE); + + return self; + } + + // TODO implement color codes + // fn color(mut self, foreground: Option, background: Option) -> Self { + // self.insert_str(0, Self::COLOR); + // self.push_str(Self::COLOR); + + // return self; + // } +} + +#[cfg(all(test, feature = "bench"))] +mod bench { + use super::*; + use test::Bencher; + + #[bench] + fn bench_mut(b: &mut Bencher) { + b.iter(|| { + let mut src = "test".to_string(); + src.bold() + }); + } + + #[bench] + fn bench_format(b: &mut Bencher) { + b.iter(|| { + let mut src = "test".to_string(); + src.italic() + }); + } +} diff --git a/src/util/formatting/truncate.rs b/src/util/formatting/truncate.rs new file mode 100644 index 0000000..c1b6257 --- /dev/null +++ b/src/util/formatting/truncate.rs @@ -0,0 +1,50 @@ +/// Truncates a string after a certain number of characters. +/// Function always tries to truncate on a word boundary. +/// Reimplemented from gonzobot. +pub fn truncate(text: &str, len: usize) -> String { + if text.len() <= len { + return text.to_string(); + } + format!( + "{}…", + text[..len] + .rsplitn(2, " ") + .collect::>() + .last() + .copied() + .expect("This can never happen >inb4 it happens") + ) +} + +#[cfg(test)] +mod tests { + use super::truncate; + + #[test] + fn test_truncate_with_input_of_lesser_length_than_limit() { + let input = "short text"; + let result = truncate(input, input.len() + 1); + assert_eq!(input, result) + } + + #[test] + fn test_truncate_with_input_of_equal_length_as_limit() { + let input = "short text"; + let result = truncate(input, input.len()); + assert_eq!(input, result) + } + + #[test] + fn test_truncate_with_input_of_greater_length_than_limit() { + let input = "some longer text"; + let result = truncate(input, input.len() - 1); + assert_eq!("some longer…", result) + } + + #[test] + fn test_truncate_with_input_of_greater_length_than_limit_oneword() { + let input = "somelongertext"; + let result = truncate(input, input.len() - 1); + assert_eq!("somelongertex…", result) + } +} -- cgit v1.2.3