From 165077ed2179210c138b34b32f4318c65c1ee6ee Mon Sep 17 00:00:00 2001 From: Fabrice Reix Date: Wed, 29 May 2024 16:24:05 +0200 Subject: [PATCH] Add RichText type --- packages/hurl_core/src/lib.rs | 1 + packages/hurl_core/src/richtext/mod.rs | 127 +++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 packages/hurl_core/src/richtext/mod.rs diff --git a/packages/hurl_core/src/lib.rs b/packages/hurl_core/src/lib.rs index 06e985aa5..247b79cca 100644 --- a/packages/hurl_core/src/lib.rs +++ b/packages/hurl_core/src/lib.rs @@ -19,3 +19,4 @@ pub mod ast; pub mod error; pub mod format; pub mod parser; +pub mod richtext; diff --git a/packages/hurl_core/src/richtext/mod.rs b/packages/hurl_core/src/richtext/mod.rs new file mode 100644 index 000000000..efc0f956e --- /dev/null +++ b/packages/hurl_core/src/richtext/mod.rs @@ -0,0 +1,127 @@ +/* + * Hurl (https://hurl.dev) + * Copyright (C) 2024 Orange + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +use colored::Colorize; + +/// An String with color and style +#[derive(Clone, Debug, PartialEq, Eq)] +#[allow(unused)] +struct RichText<'a> { + tokens: Vec>, +} + +#[allow(unused)] +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum Format { + Plain, + Ansi, +} + +#[allow(unused)] +#[derive(Clone, Debug, PartialEq, Eq)] +struct Token<'a> { + content: &'a str, + fg: Option, + bold: bool, +} + +#[allow(unused)] +#[derive(Clone, Debug, PartialEq, Eq)] +enum Color { + Red, + Green, + Blue, +} + +#[allow(unused)] +impl<'a> RichText<'a> { + pub fn new() -> RichText<'a> { + RichText { tokens: vec![] } + } + + pub fn add_token(&mut self, content: &'a str, fg: Option, bold: bool) { + let token = Token::new(content, fg, bold); + self.tokens.push(token); + } + + pub fn text(mut self, content: &'a str) -> RichText { + self.add_token(content, None, false); + self + } + + pub fn red(mut self, content: &'a str) -> RichText { + self.add_token(content, Some(Color::Red), false); + self + } + + pub fn to_string(&self, format: Format) -> String { + self.tokens + .iter() + .map(|token| token.to_string(format)) + .collect::>() + .join("") + } +} + +impl<'a> Token<'a> { + pub fn new(content: &'a str, fg: Option, bold: bool) -> Token { + Token { content, fg, bold } + } + + pub fn to_string(&self, format: Format) -> String { + match format { + Format::Plain => self.plain(), + Format::Ansi => self.ansi(), + } + } + + fn plain(&self) -> String { + self.content.to_string() + } + + fn ansi(&self) -> String { + let mut s = self.content.to_string(); + if let Some(color) = &self.fg { + s = match color { + Color::Red => s.red().to_string(), + Color::Green => s.green().to_string(), + Color::Blue => s.blue().to_string(), + }; + } + if self.bold { + s = s.bold().to_string(); + } + s + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_hello() { + colored::control::set_override(true); + let message = RichText::new().text("Hello ").red("Bob").text("!"); + assert_eq!(message.to_string(Format::Plain), "Hello Bob!"); + assert_eq!( + message.to_string(Format::Ansi), + "Hello \u{1b}[31mBob\u{1b}[0m!" + ); + } +}