#[cfg(feature = "std")]
use std::{
format,
string::{String, ToString},
};
#[derive(Clone, Debug, Default)]
pub struct HtmlCustomization {
pub custom_css: Option<String>,
pub logo_url: Option<String>,
pub logo_alt: Option<String>,
pub custom_js: Option<String>,
pub replace_css: Option<String>,
pub replace_js: Option<String>,
pub footer_html: Option<String>,
pub header_html: Option<String>,
pub accent_color: Option<String>,
pub accent_color_dark: Option<String>,
}
impl HtmlCustomization {
pub fn new() -> Self {
Self::default()
}
pub fn with_custom_css(mut self, css: impl Into<String>) -> Self {
self.custom_css = Some(css.into());
self
}
pub fn with_logo(mut self, url: impl Into<String>, alt: impl Into<String>) -> Self {
self.logo_url = Some(url.into());
self.logo_alt = Some(alt.into());
self
}
pub fn with_accent_color(mut self, light: impl Into<String>, dark: impl Into<String>) -> Self {
self.accent_color = Some(light.into());
self.accent_color_dark = Some(dark.into());
self
}
pub fn with_custom_js(mut self, js: impl Into<String>) -> Self {
self.custom_js = Some(js.into());
self
}
pub fn with_footer(mut self, html: impl Into<String>) -> Self {
self.footer_html = Some(html.into());
self
}
pub fn with_header(mut self, html: impl Into<String>) -> Self {
self.header_html = Some(html.into());
self
}
pub fn replace_css(mut self, css: impl Into<String>) -> Self {
self.replace_css = Some(css.into());
self
}
pub fn replace_js(mut self, js: impl Into<String>) -> Self {
self.replace_js = Some(js.into());
self
}
pub(crate) fn generate_css_variables(&self) -> String {
if let (Some(light), Some(dark)) = (&self.accent_color, &self.accent_color_dark) {
format!(
r#"
:root {{
--accent-color: {};
--accent-hover: {};
}}
@media (prefers-color-scheme: dark) {{
:root {{
--accent-color: {};
--accent-hover: {};
}}
}}
"#,
light,
Self::adjust_brightness(light, 0.9),
dark,
Self::adjust_brightness(dark, 1.1)
)
} else if let Some(light) = &self.accent_color {
format!(
r#"
:root {{
--accent-color: {};
--accent-hover: {};
}}
"#,
light,
Self::adjust_brightness(light, 0.9)
)
} else {
String::new()
}
}
fn adjust_brightness(color: &str, _factor: f32) -> String {
color.to_string()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_builder_pattern() {
let custom = HtmlCustomization::new()
.with_logo("logo.svg", "My Logo")
.with_accent_color("#FF5722", "#FF8A65")
.with_custom_css(".custom { color: red; }");
assert!(custom.logo_url.is_some());
assert!(custom.accent_color.is_some());
assert!(custom.custom_css.is_some());
}
#[test]
fn test_css_variables_generation() {
let custom = HtmlCustomization::new().with_accent_color("#FF5722", "#FF8A65");
let css = custom.generate_css_variables();
assert!(css.contains("--accent-color: #FF5722"));
assert!(css.contains("--accent-color: #FF8A65"));
}
}