Framework for embedding localizations into Rust types
use crate::Localize;

use anstyle::{AnsiColor, Color, Style};

macro_rules! style_attribute {
    ($function_name:ident) => {
        pub fn $function_name(mut self) -> Self {
            self.style = self.style.map(|style| style.$function_name());

            self
        }
    };
}

pub struct Styled<L: Localize> {
    message: L,
    style: Option<Style>,
}

impl<L: Localize> Localize for Styled<L> {
    fn localize_for(&self, locale: &icu_locale::Locale) -> String {
        let message = self.message.localize_for(locale);
        match self.style {
            Some(style) => format!("{style}{message}{style:#}"),
            None => message,
        }
    }
}

impl<L: Localize> Styled<L> {
    pub fn new(message: L, enabled: bool) -> Self {
        Self {
            message,
            style: match enabled {
                true => Some(Style::new()),
                false => None,
            },
        }
    }

    style_attribute!(bold);
    style_attribute!(dimmed);
    style_attribute!(italic);
    style_attribute!(strikethrough);

    pub fn color(mut self, color: AnsiColor) -> Self {
        self.style = self
            .style
            .map(|style| style.fg_color(Some(Color::Ansi(color))));

        self
    }
}