diff --git a/pagetop/src/module/all.rs b/pagetop/src/module/all.rs index 6380917a..2e499f23 100644 --- a/pagetop/src/module/all.rs +++ b/pagetop/src/module/all.rs @@ -19,7 +19,7 @@ pub fn register_module(module: &'static dyn ModuleTrait) { fn add_to(list: &mut Vec<&dyn ModuleTrait>, module: &'static dyn ModuleTrait) { if !MODULES.read().unwrap().iter().any(|m| m.name() == module.name()) { if !list.iter().any(|m| m.name() == module.name()) { - trace::debug!("Registering \"{}\" module", module.name()); + trace::debug!("Registering \"{}\" module", module.single_name()); list.push(module); let mut dependencies = module.dependencies(); diff --git a/pagetop/src/module/definition.rs b/pagetop/src/module/definition.rs index a3affa2f..baaadd98 100644 --- a/pagetop/src/module/definition.rs +++ b/pagetop/src/module/definition.rs @@ -1,22 +1,31 @@ use crate::app; +use crate::util::partial_type_name; #[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))] use crate::db; +pub trait BaseModule { + fn type_name(&self) -> &'static str; + + fn single_name(&self) -> &'static str; + + fn qualified_name(&self, last: usize) -> &'static str; +} + /// Los módulos deben implementar este *trait*. -pub trait ModuleTrait: Send + Sync { - fn name(&self) -> &'static str; - - fn fullname(&self) -> String; - - fn dependencies(&self) -> Vec<&'static dyn ModuleTrait> { - vec![] +pub trait ModuleTrait: BaseModule + Send + Sync { + fn name(&self) -> String { + self.single_name().to_owned() } fn description(&self) -> Option { None } + fn dependencies(&self) -> Vec<&'static dyn ModuleTrait> { + vec![] + } + #[allow(unused_variables)] fn configure_module(&self, cfg: &mut app::web::ServiceConfig) { } @@ -27,3 +36,17 @@ pub trait ModuleTrait: Send + Sync { vec![] } } + +impl BaseModule for M { + fn type_name(&self) -> &'static str { + std::any::type_name::() + } + + fn single_name(&self) -> &'static str { + partial_type_name(std::any::type_name::(), 1) + } + + fn qualified_name(&self, last: usize) -> &'static str { + partial_type_name(std::any::type_name::(), last) + } +} diff --git a/pagetop/src/module/mod.rs b/pagetop/src/module/mod.rs index a767683b..720d806c 100644 --- a/pagetop/src/module/mod.rs +++ b/pagetop/src/module/mod.rs @@ -1,5 +1,8 @@ mod definition; -pub use definition::ModuleTrait; +pub use definition::{ + BaseModule, + ModuleTrait, +}; pub(crate) mod all; pub use all::register_module; \ No newline at end of file diff --git a/pagetop/src/response/page/component.rs b/pagetop/src/response/page/component.rs index 8839a5ca..a423707f 100644 --- a/pagetop/src/response/page/component.rs +++ b/pagetop/src/response/page/component.rs @@ -1,24 +1,23 @@ use crate::html::{Markup, html}; use crate::response::page::PageAssets; - -use std::any::type_name; +use crate::util::partial_type_name; pub use std::any::Any as AnyComponent; -pub trait ComponentTrait: AnyComponent + Send + Sync { +pub trait BaseComponent { + fn type_name(&self) -> &'static str; + + fn single_name(&self) -> &'static str; + + fn qualified_name(&self, last: usize) -> &'static str; +} + +pub trait ComponentTrait: AnyComponent + BaseComponent + Send + Sync { fn new() -> Self where Self: Sized; - fn name(&self) -> &'static str { - let name = type_name::(); - match name.rfind("::") { - Some(position) => &name[(position + 2)..], - None => name - } - } - - fn fullname(&self) -> String { - type_name::().to_owned() + fn name(&self) -> String { + self.single_name().to_owned() } fn description(&self) -> Option { @@ -47,10 +46,24 @@ pub trait ComponentTrait: AnyComponent + Send + Sync { fn as_mut_any(&mut self) -> &mut dyn AnyComponent; } -pub fn component_ref(component: &dyn ComponentTrait) -> &T { - component.as_ref_any().downcast_ref::().unwrap() +impl BaseComponent for C { + fn type_name(&self) -> &'static str { + std::any::type_name::() + } + + fn single_name(&self) -> &'static str { + partial_type_name(std::any::type_name::(), 1) + } + + fn qualified_name(&self, last: usize) -> &'static str { + partial_type_name(std::any::type_name::(), last) + } } -pub fn component_mut(component: &mut dyn ComponentTrait) -> &mut T { - component.as_mut_any().downcast_mut::().unwrap() +pub fn component_ref(component: &dyn ComponentTrait) -> &C { + component.as_ref_any().downcast_ref::().unwrap() +} + +pub fn component_mut(component: &mut dyn ComponentTrait) -> &mut C { + component.as_mut_any().downcast_mut::().unwrap() } diff --git a/pagetop/src/response/page/mod.rs b/pagetop/src/response/page/mod.rs index 1d923f73..01add24f 100644 --- a/pagetop/src/response/page/mod.rs +++ b/pagetop/src/response/page/mod.rs @@ -9,6 +9,7 @@ pub use assets::{ mod component; pub use component::{ AnyComponent, + BaseComponent, ComponentTrait, component_ref, component_mut, diff --git a/pagetop/src/theme/all.rs b/pagetop/src/theme/all.rs index ee0bfedb..12d96338 100644 --- a/pagetop/src/theme/all.rs +++ b/pagetop/src/theme/all.rs @@ -13,7 +13,7 @@ static THEMES: Lazy>> = Lazy::new(|| { pub fn register_theme(theme: &'static dyn ThemeTrait) { let mut themes = THEMES.write().unwrap(); if !themes.iter().any(|t| t.name() == theme.name()) { - trace::debug!("Registering \"{}\" theme", theme.name()); + trace::debug!("Registering \"{}\" theme", theme.single_name()); themes.push(theme); } } diff --git a/pagetop/src/theme/definition.rs b/pagetop/src/theme/definition.rs index 4d54d758..ef21491a 100644 --- a/pagetop/src/theme/definition.rs +++ b/pagetop/src/theme/definition.rs @@ -3,12 +3,21 @@ use crate::config::SETTINGS; use crate::html::{Markup, html}; use crate::response::page::{ComponentTrait, Favicon, Page, PageAssets}; use crate::base::component::Chunck; +use crate::util::partial_type_name; + +pub trait BaseTheme { + fn type_name(&self) -> &'static str; + + fn single_name(&self) -> &'static str; + + fn qualified_name(&self, last: usize) -> &'static str; +} /// Los temas deben implementar este "trait". -pub trait ThemeTrait: Send + Sync { - fn name(&self) -> &'static str; - - fn fullname(&self) -> String; +pub trait ThemeTrait: BaseTheme + Send + Sync { + fn name(&self) -> String { + self.single_name().to_owned() + } fn description(&self) -> Option { None @@ -127,3 +136,17 @@ pub trait ThemeTrait: Send + Sync { .render() } } + +impl BaseTheme for T { + fn type_name(&self) -> &'static str { + std::any::type_name::() + } + + fn single_name(&self) -> &'static str { + partial_type_name(std::any::type_name::(), 1) + } + + fn qualified_name(&self, last: usize) -> &'static str { + partial_type_name(std::any::type_name::(), last) + } +} diff --git a/pagetop/src/theme/mod.rs b/pagetop/src/theme/mod.rs index 4456189e..f76d1fe3 100644 --- a/pagetop/src/theme/mod.rs +++ b/pagetop/src/theme/mod.rs @@ -1,5 +1,8 @@ mod definition; -pub use definition::ThemeTrait; +pub use definition::{ + BaseTheme, + ThemeTrait, +}; pub(crate) mod all; pub use all::{ diff --git a/pagetop/src/util.rs b/pagetop/src/util.rs index 02bb584e..ca4a96fc 100644 --- a/pagetop/src/util.rs +++ b/pagetop/src/util.rs @@ -46,3 +46,14 @@ macro_rules! theme_static_files { } }}; } + +pub(crate) fn partial_type_name(type_name: &'static str, last: usize) -> &'static str { + if last == 0 { + return type_name; + } + let positions: Vec<_> = type_name.rmatch_indices("::").collect(); + if positions.len() < last { + return type_name; + } + &type_name[(positions[last - 1].0 + 2)..] +}