///|
/// A reusable ANSI text style. Predefined colors use lowercase constructors
/// in place of Rust's associated constants.
pub struct Color {
priv ansi : @papergrid.ANSIBuf
priv static_ : Bool
} derive(Eq, Debug)
///|
pub fn Color::new(prefix : String, suffix : String) -> Color {
{ ansi: @papergrid.ANSIBuf::new(prefix, suffix), static_: false, }
}
///|
fn Color::new_static(prefix : String, suffix : String) -> Color {
{ ansi: @papergrid.ANSIBuf::new(prefix, suffix), static_: true, }
}
///|
pub fn Color::empty() -> Color {
Color::new_static("", "")
}
///|
pub fn Color::default() -> Color {
Color::empty()
}
///|
/// Extract the style of the first text block; no text block produces Err.
pub fn Color::try_parse(text : String) -> Result[Color, Unit] {
@papergrid.ANSIBuf::try_parse(text).map(Color::from_ansi_buf)
}
///|
/// Parse a style, aborting on input without a text block. Use `try_parse` when
/// a missing text block must be handled explicitly.
pub fn Color::parse_or_abort(text : String) -> Color {
match Color::try_parse(text) {
Ok(color) => color
Err(_) => abort("Color::parse_or_abort requires a text block")
}
}
///|
pub fn Color::is_empty(self : Color) -> Bool {
self.ansi.is_empty()
}
///|
pub fn Color::get_prefix(self : Color) -> String {
self.ansi.prefix
}
///|
pub fn Color::get_suffix(self : Color) -> String {
self.ansi.suffix
}
///|
/// Return a style pair only for colors created from a static preset or ANSIStr.
/// Dynamically parsed or constructed colors return None; use `to_ansi_buf` for those.
pub fn Color::as_static_ansi(self : Color) -> @papergrid.ANSIStr? {
if self.static_ {
Some(self.ansi.as_ansi_str())
} else {
None
}
}
///|
pub fn Color::to_ansi_buf(self : Color) -> @papergrid.ANSIBuf {
self.ansi
}
///|
pub fn Color::from_ansi_buf(ansi : @papergrid.ANSIBuf) -> Color {
{ ansi, static_: false, }
}
///|
pub fn Color::from_ansi_str(ansi : @papergrid.ANSIStr) -> Color {
{ ansi: @papergrid.ANSIBuf::from_ansi_str(ansi), static_: true, }
}
///|
pub impl @papergrid.ANSIFmt for Color with fn fmt_ansi_prefix(self, out) {
out.write_string(self.ansi.prefix)
}
///|
pub impl @papergrid.ANSIFmt for Color with fn fmt_ansi_suffix(self, out) {
out.write_string(self.ansi.suffix)
}
///|
pub fn Color::fg_rgb(red : Byte, green : Byte, blue : Byte) -> Color {
Color::new(
"\u001b[38;2;\{red.to_int()};\{green.to_int()};\{blue.to_int()}m",
"\u001b[39m",
)
}
///|
pub fn Color::bg_rgb(red : Byte, green : Byte, blue : Byte) -> Color {
Color::new(
"\u001b[48;2;\{red.to_int()};\{green.to_int()};\{blue.to_int()}m",
"\u001b[49m",
)
}
///|
/// Combine styles in order, deduplicating identical prefixes or suffixes.
pub fn Color::combine(self : Color, other : Color) -> Color {
Color::new(
self.ansi.prefix +
(if self.ansi.prefix == other.ansi.prefix { "" } else { other.ansi.prefix }),
self.ansi.suffix +
(if self.ansi.suffix == other.ansi.suffix { "" } else { other.ansi.suffix }),
)
}
///|
pub impl BitOr for Color with fn lor(self, other) {
self.combine(other)
}
///|
/// Color each logical line separately; a trailing newline is omitted, as in tabled.
pub fn Color::colorize(self : Color, text : String) -> String {
guard !text.is_empty() else { return "" }
let lines = @papergrid.split_lines(text)
if text.has_suffix("\n") {
lines.pop() |> ignore
}
let result = []
for index, line in lines {
let line = if line.has_suffix("\r") &&
(index + 1 < lines.length() || text.has_suffix("\n")) {
line[:line.length() - 1].to_owned()
} else {
line
}
result.push(self.ansi.prefix + line + self.ansi.suffix)
}
result.join("\n")
}
///|
pub impl CellOption for Color with fn change(self, table, entity) {
table.config.set_color(entity, Some(self.ansi))
}
///|
pub impl TableOption for Color with fn change(self, table) {
CellOption::change(self, table, Entity::Global)
}
///|
pub impl CellOption for Color with fn hint_change(_self) {
None
}
///|
pub impl TableOption for Color with fn hint_change(_self) {
None
}
///|
pub extend Color with Eq::{not_equal, equal}
///|
pub extend Color with @debug.Debug::{to_repr}
///|
pub extend Color with @papergrid.ANSIFmt::{fmt_ansi_suffix, fmt_ansi_prefix}
///|
pub extend Color with BitOr::{lor}
///|
pub extend Color with CellOption::{
change as change_cell,
hint_change as hint_change_cell,
}
///|
pub extend Color with TableOption::{change, hint_change}