Añade extensiones en módulos para añadir funciones
This commit is contained in:
parent
8f429401eb
commit
9eede3321a
7 changed files with 96 additions and 26 deletions
|
|
@ -1,14 +1,20 @@
|
|||
use crate::{Lazy, app, run_now, trace};
|
||||
use crate::db::*;
|
||||
use super::ModuleTrait;
|
||||
use super::{ExtensionTrait, ModuleTrait};
|
||||
|
||||
use std::sync::RwLock;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::collections::HashMap;
|
||||
|
||||
// Módulos registrados.
|
||||
static MODULES: Lazy<RwLock<Vec<&dyn ModuleTrait>>> = Lazy::new(|| {
|
||||
RwLock::new(Vec::new())
|
||||
});
|
||||
|
||||
// Extensiones registradas.
|
||||
static EXTENSIONS: Lazy<RwLock<HashMap<&str, Arc<Vec<&dyn ExtensionTrait>>>>> = Lazy::new(|| {
|
||||
RwLock::new(HashMap::new())
|
||||
});
|
||||
|
||||
pub fn register_module(module: &'static dyn ModuleTrait) {
|
||||
let mut list: Vec<&dyn ModuleTrait> = Vec::new();
|
||||
add_to(&mut list, module);
|
||||
|
|
@ -17,11 +23,24 @@ 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()) {
|
||||
if !MODULES.read().unwrap().iter().any(|m| m.type_name() == module.type_name()) {
|
||||
if !list.iter().any(|m| m.type_name() == module.type_name()) {
|
||||
trace::debug!("Registering \"{}\" module", module.single_name());
|
||||
list.push(module);
|
||||
|
||||
|
||||
let mut hmap = EXTENSIONS.write().unwrap();
|
||||
for e in module.extensions().iter() {
|
||||
if let Some(extensions) = hmap.get_mut(e.type_name()) {
|
||||
let v = Arc::get_mut(extensions).unwrap();
|
||||
v.push(*e);
|
||||
v.sort_by_key(|e| e.weight());
|
||||
} else {
|
||||
hmap.insert(e.type_name(), Arc::new(vec![*e]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let mut dependencies = module.dependencies();
|
||||
dependencies.reverse();
|
||||
for d in dependencies.iter() {
|
||||
|
|
@ -37,6 +56,13 @@ pub fn modules(cfg: &mut app::web::ServiceConfig) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn extensions(type_name: &'static str) -> Option<Arc<Vec<&dyn ExtensionTrait>>> {
|
||||
match EXTENSIONS.read().unwrap().get(type_name) {
|
||||
Some(extensions) => Some(extensions.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
pub fn migrations() {
|
||||
run_now({
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
use crate::app;
|
||||
use crate::util::partial_type_name;
|
||||
use crate::{app, util};
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
use crate::db;
|
||||
|
||||
use super::ExtensionTrait;
|
||||
|
||||
pub trait BaseModule {
|
||||
fn type_name(&self) -> &'static str;
|
||||
|
||||
fn single_name(&self) -> &'static str;
|
||||
|
||||
fn qualified_name(&self, last: usize) -> &'static str;
|
||||
fn qualified_name(&self, last: u8) -> &'static str;
|
||||
}
|
||||
|
||||
/// Los módulos deben implementar este *trait*.
|
||||
|
|
@ -22,19 +23,23 @@ pub trait ModuleTrait: BaseModule + Send + Sync {
|
|||
None
|
||||
}
|
||||
|
||||
fn dependencies(&self) -> Vec<&'static dyn ModuleTrait> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn configure_module(&self, cfg: &mut app::web::ServiceConfig) {
|
||||
}
|
||||
|
||||
fn extensions(&self) -> Vec<&'static dyn ExtensionTrait> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
#[allow(unused_variables)]
|
||||
fn migrations(&self) -> Vec<Box<dyn db::MigrationTrait>> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn dependencies(&self) -> Vec<&'static dyn ModuleTrait> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: ?Sized + ModuleTrait> BaseModule for M {
|
||||
|
|
@ -43,10 +48,10 @@ impl<M: ?Sized + ModuleTrait> BaseModule for M {
|
|||
}
|
||||
|
||||
fn single_name(&self) -> &'static str {
|
||||
partial_type_name(std::any::type_name::<Self>(), 1)
|
||||
util::partial_type_name(std::any::type_name::<Self>(), 1)
|
||||
}
|
||||
|
||||
fn qualified_name(&self, last: usize) -> &'static str {
|
||||
partial_type_name(std::any::type_name::<Self>(), last)
|
||||
fn qualified_name(&self, last: u8) -> &'static str {
|
||||
util::partial_type_name(std::any::type_name::<Self>(), last)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
30
pagetop/src/core/module/extension.rs
Normal file
30
pagetop/src/core/module/extension.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
use crate::util;
|
||||
|
||||
pub trait BaseExtension {
|
||||
fn type_name(&self) -> &'static str;
|
||||
|
||||
fn single_name(&self) -> &'static str;
|
||||
|
||||
fn qualified_name(&self, last: u8) -> &'static str;
|
||||
}
|
||||
|
||||
/// Las extensiones deben extender este *trait*.
|
||||
pub trait ExtensionTrait: BaseExtension + Send + Sync {
|
||||
fn weight(&self) -> i8 {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: ?Sized + ExtensionTrait> BaseExtension for E {
|
||||
fn type_name(&self) -> &'static str {
|
||||
std::any::type_name::<Self>()
|
||||
}
|
||||
|
||||
fn single_name(&self) -> &'static str {
|
||||
util::partial_type_name(std::any::type_name::<Self>(), 1)
|
||||
}
|
||||
|
||||
fn qualified_name(&self, last: u8) -> &'static str {
|
||||
util::partial_type_name(std::any::type_name::<Self>(), last)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,14 @@ pub use definition::{
|
|||
BaseModule,
|
||||
ModuleTrait,
|
||||
};
|
||||
mod extension;
|
||||
pub use extension::{
|
||||
BaseExtension,
|
||||
ExtensionTrait,
|
||||
};
|
||||
|
||||
pub(crate) mod all;
|
||||
pub use all::register_module;
|
||||
pub use all::{
|
||||
extensions,
|
||||
register_module
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::html::{Markup, html};
|
||||
use crate::core::response::page::PageAssets;
|
||||
use crate::util::partial_type_name;
|
||||
use crate::util;
|
||||
|
||||
pub use std::any::Any as AnyComponent;
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ pub trait BaseComponent {
|
|||
|
||||
fn single_name(&self) -> &'static str;
|
||||
|
||||
fn qualified_name(&self, last: usize) -> &'static str;
|
||||
fn qualified_name(&self, last: u8) -> &'static str;
|
||||
}
|
||||
|
||||
pub trait ComponentTrait: AnyComponent + BaseComponent + Send + Sync {
|
||||
|
|
@ -52,11 +52,11 @@ impl<C: ?Sized + ComponentTrait> BaseComponent for C {
|
|||
}
|
||||
|
||||
fn single_name(&self) -> &'static str {
|
||||
partial_type_name(std::any::type_name::<Self>(), 1)
|
||||
util::partial_type_name(std::any::type_name::<Self>(), 1)
|
||||
}
|
||||
|
||||
fn qualified_name(&self, last: usize) -> &'static str {
|
||||
partial_type_name(std::any::type_name::<Self>(), last)
|
||||
fn qualified_name(&self, last: u8) -> &'static str {
|
||||
util::partial_type_name(std::any::type_name::<Self>(), last)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ use crate::config::SETTINGS;
|
|||
use crate::html::{Markup, html};
|
||||
use crate::core::response::page::{ComponentTrait, Favicon, Page, PageAssets};
|
||||
use crate::base::component::Chunck;
|
||||
use crate::util::partial_type_name;
|
||||
use crate::util;
|
||||
|
||||
pub trait BaseTheme {
|
||||
fn type_name(&self) -> &'static str;
|
||||
|
||||
fn single_name(&self) -> &'static str;
|
||||
|
||||
fn qualified_name(&self, last: usize) -> &'static str;
|
||||
fn qualified_name(&self, last: u8) -> &'static str;
|
||||
}
|
||||
|
||||
/// Los temas deben implementar este "trait".
|
||||
|
|
@ -143,10 +143,10 @@ impl<T: ?Sized + ThemeTrait> BaseTheme for T {
|
|||
}
|
||||
|
||||
fn single_name(&self) -> &'static str {
|
||||
partial_type_name(std::any::type_name::<Self>(), 1)
|
||||
util::partial_type_name(std::any::type_name::<Self>(), 1)
|
||||
}
|
||||
|
||||
fn qualified_name(&self, last: usize) -> &'static str {
|
||||
partial_type_name(std::any::type_name::<Self>(), last)
|
||||
fn qualified_name(&self, last: u8) -> &'static str {
|
||||
util::partial_type_name(std::any::type_name::<Self>(), last)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,11 +47,12 @@ macro_rules! theme_static_files {
|
|||
}};
|
||||
}
|
||||
|
||||
pub(crate) fn partial_type_name(type_name: &'static str, last: usize) -> &'static str {
|
||||
pub(crate) fn partial_type_name(type_name: &'static str, last: u8) -> &'static str {
|
||||
if last == 0 {
|
||||
return type_name;
|
||||
}
|
||||
let positions: Vec<_> = type_name.rmatch_indices("::").collect();
|
||||
let last: usize = last as usize;
|
||||
if positions.len() < last {
|
||||
return type_name;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue