use crate::base::component::add_base_assets; use crate::core::theme::all::{theme_by_single_name, THEME}; use crate::core::theme::ThemeRef; use crate::html::{html, Assets, HeadScript, HeadStyles, JavaScript, Markup, StyleSheet}; use crate::locale::{LanguageIdentifier, LANGID}; use crate::service::HttpRequest; use crate::{concat_string, util}; use std::collections::HashMap; use std::str::FromStr; pub enum ContextOp { LangId(&'static LanguageIdentifier), Theme(&'static str), // Stylesheets. AddStyleSheet(StyleSheet), RemoveStyleSheet(&'static str), // Styles in head. AddHeadStyles(HeadStyles), RemoveHeadStyles(&'static str), // JavaScripts. AddJavaScript(JavaScript), RemoveJavaScript(&'static str), // Scripts in head. AddHeadScript(HeadScript), RemoveHeadScript(&'static str), // Add assets to properly use base components. AddBaseAssets, } #[rustfmt::skip] pub struct Context { request : HttpRequest, langid : &'static LanguageIdentifier, theme : ThemeRef, stylesheet: Assets, // Stylesheets. headstyles: Assets, // Styles in head. javascript: Assets, // JavaScripts. headscript: Assets, // Scripts in head. params : HashMap<&'static str, String>, id_counter: usize, } impl Context { #[rustfmt::skip] pub(crate) fn new(request: HttpRequest) -> Self { Context { request, langid : &LANGID, theme : *THEME, stylesheet: Assets::::new(), // Stylesheets. headstyles: Assets::::new(), // Styles in head. javascript: Assets::::new(), // JavaScripts. headscript: Assets::::new(), // Scripts in head. params : HashMap::<&str, String>::new(), id_counter: 0, } } #[rustfmt::skip] pub fn alter(&mut self, op: ContextOp) -> &mut Self { match op { ContextOp::LangId(langid) => { self.langid = langid; } ContextOp::Theme(theme_name) => { self.theme = theme_by_single_name(theme_name).unwrap_or(*THEME); } // Stylesheets. ContextOp::AddStyleSheet(css) => { self.stylesheet.add(css); } ContextOp::RemoveStyleSheet(path) => { self.stylesheet.remove(path); } // Styles in head. ContextOp::AddHeadStyles(styles) => { self.headstyles.add(styles); } ContextOp::RemoveHeadStyles(path) => { self.headstyles.remove(path); } // JavaScripts. ContextOp::AddJavaScript(js) => { self.javascript.add(js); } ContextOp::RemoveJavaScript(path) => { self.javascript.remove(path); } // Scripts in head. ContextOp::AddHeadScript(script) => { self.headscript.add(script); } ContextOp::RemoveHeadScript(path) => { self.headscript.remove(path); } // Add assets to properly use base components. ContextOp::AddBaseAssets => { add_base_assets(self); } } self } pub fn set_param(&mut self, key: &'static str, value: T) -> &mut Self { self.params.insert(key, value.to_string()); self } pub fn remove_param(&mut self, key: &'static str) -> &mut Self { self.params.remove(key); self } /// Context GETTERS. pub fn request(&self) -> &HttpRequest { &self.request } pub fn langid(&self) -> &LanguageIdentifier { self.langid } pub fn theme(&self) -> ThemeRef { self.theme } pub fn get_param(&mut self, key: &'static str) -> Option { if let Some(value) = self.params.get(key) { if let Ok(value) = T::from_str(value) { return Some(value); } } None } /// Context PREPARE. pub fn prepare(&mut self) -> Markup { html! { (self.stylesheet.prepare()) // Stylesheets. (self.headstyles.prepare()) // Styles in head. (self.javascript.prepare()) // JavaScripts. (self.headscript.prepare()) // Scripts in head. } } // Context EXTRAS. pub fn required_id(&mut self, id: Option) -> String { match id { Some(id) => id, None => { let prefix = util::single_type_name::() .trim() .replace(' ', "_") .to_lowercase(); let prefix = if prefix.is_empty() { "prefix".to_owned() } else { prefix }; self.id_counter += 1; concat_string!(prefix, "-", self.id_counter.to_string()) } } } }