log4wasm 0.1.3

A stylish rust-generated WebAssembly logging utility.
Documentation
use std::fmt::{Display, Formatter, Result as FmtResult};

/// Color codes represented in the form of the [ANSI](https://en.wikipedia.org/wiki/ANSI_escape_code)-equivalent color code.
#[derive(Copy, Clone, Debug)]
#[allow(unused)]
pub enum Color {
    Black = 30,
    Red = 31,
    Green = 32,
    Yellow = 33,
    Blue = 34,
    Purple = 35,
    Cyan = 36,
    White = 37,
    BrightRed = 91,
}

impl Color {

    #[allow(unused)]
    pub(crate) fn wrap(&self, content: impl Display) -> Styled {
        Styled::with_content(content).colored(*self)
    }
}

#[derive(Copy, Clone, Debug)]
#[allow(unused)]
pub enum Decoration {
    Bold = 1,
    Underline = 4
}

impl Decoration {

    #[allow(unused)]
    pub(crate) fn wrap(&self, content: impl Display) -> Styled {
        Styled::with_content(content)
    }
}

/// Provides styling capabilities to be applied on a log output.
/// 
/// ```rust,no_run
/// use log4wasm::styled::{Color, Styled, Decoration};
/// 
/// // Construct the styling, building it into a StyledLog, to be written to the console.
/// let styled_log = Styled::with_content(format!("Are we styled yet? Yezzir! {}", "Frfr?"))
/// .colored(Color::Red)
/// .decorate(Decoration::Bold)
/// .into_log();
/// ```
/// 
#[derive(Debug, Default)]
pub struct Styled {
    settings: usize,
    content: String,
}

impl Styled {
    pub(crate) const ESC: char = '\x1b';
    pub(crate) const TERMINATOR: &str = "\x1b[0m";
    
    /// Construct a new, default Styled object. The default values produce an unstyled output, allowing for a style to be
    /// created from the ground up.
    pub fn new() -> Self {
        Self::default()
    }

    /// Constructs a new Styled object, setting its content to the passed-in value.
    pub fn with_content(content: impl Display) -> Self {
        Self { settings: 0, content: format!("{}", content) }
    }

    /// Sets the [Color] style to be applied on the associated content.
    pub fn colored(mut self, color: Color) -> Self {
        self.settings |= (color as usize) << 16;
        self
    }

    /// Sets the [Decoration] style to be applied on the associated content.
    pub fn decorate(mut self, decoration: Decoration) -> Self {
        self.settings |= decoration as usize;
        self
    }

    fn fmt(Self { settings, content }: Self) -> String {
        let has_decoration = settings & 0xFFFF != 0;
        let color_args = settings >> 16;
        if has_decoration {
            format!("{}[{};{}m{}{}", Styled::ESC, settings & 0xFFFF, color_args, content, Styled::TERMINATOR)
        } else {
            format!("{}[{}m{}{}", Styled::ESC, color_args, content, Styled::TERMINATOR)
        }
    }

    /// Finalizes the styling process, consuming its reference, by building a [StyledLog] reflecting the properties set during
    /// the composition of this Styled object.
    pub fn into_log(self) -> StyledLog {
        StyledLog(Self::fmt(self))
    }
}

impl From<Styled> for StyledLog {
    fn from(value: Styled) -> Self {
        Self(Styled::fmt(value))
    }
}

#[derive(Clone)]
#[wasm_bindgen::prelude::wasm_bindgen]
pub struct StyledLog(String);

impl Display for StyledLog {
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        write!(f, "{}", self.0)
    }
}