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::{Lazy, app, run_now, trace};
|
||||||
use crate::db::*;
|
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.
|
// Módulos registrados.
|
||||||
static MODULES: Lazy<RwLock<Vec<&dyn ModuleTrait>>> = Lazy::new(|| {
|
static MODULES: Lazy<RwLock<Vec<&dyn ModuleTrait>>> = Lazy::new(|| {
|
||||||
RwLock::new(Vec::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) {
|
pub fn register_module(module: &'static dyn ModuleTrait) {
|
||||||
let mut list: Vec<&dyn ModuleTrait> = Vec::new();
|
let mut list: Vec<&dyn ModuleTrait> = Vec::new();
|
||||||
add_to(&mut list, module);
|
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) {
|
fn add_to(list: &mut Vec<&dyn ModuleTrait>, module: &'static dyn ModuleTrait) {
|
||||||
if !MODULES.read().unwrap().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.name() == module.name()) {
|
if !list.iter().any(|m| m.type_name() == module.type_name()) {
|
||||||
trace::debug!("Registering \"{}\" module", module.single_name());
|
trace::debug!("Registering \"{}\" module", module.single_name());
|
||||||
list.push(module);
|
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();
|
let mut dependencies = module.dependencies();
|
||||||
dependencies.reverse();
|
dependencies.reverse();
|
||||||
for d in dependencies.iter() {
|
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"))]
|
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||||
pub fn migrations() {
|
pub fn migrations() {
|
||||||
run_now({
|
run_now({
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
use crate::app;
|
use crate::{app, util};
|
||||||
use crate::util::partial_type_name;
|
|
||||||
|
|
||||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||||
use crate::db;
|
use crate::db;
|
||||||
|
|
||||||
|
use super::ExtensionTrait;
|
||||||
|
|
||||||
pub trait BaseModule {
|
pub trait BaseModule {
|
||||||
fn type_name(&self) -> &'static str;
|
fn type_name(&self) -> &'static str;
|
||||||
|
|
||||||
fn single_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*.
|
/// Los módulos deben implementar este *trait*.
|
||||||
|
|
@ -22,19 +23,23 @@ pub trait ModuleTrait: BaseModule + Send + Sync {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dependencies(&self) -> Vec<&'static dyn ModuleTrait> {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn configure_module(&self, cfg: &mut app::web::ServiceConfig) {
|
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"))]
|
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn migrations(&self) -> Vec<Box<dyn db::MigrationTrait>> {
|
fn migrations(&self) -> Vec<Box<dyn db::MigrationTrait>> {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dependencies(&self) -> Vec<&'static dyn ModuleTrait> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: ?Sized + ModuleTrait> BaseModule for M {
|
impl<M: ?Sized + ModuleTrait> BaseModule for M {
|
||||||
|
|
@ -43,10 +48,10 @@ impl<M: ?Sized + ModuleTrait> BaseModule for M {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn single_name(&self) -> &'static str {
|
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 {
|
fn qualified_name(&self, last: u8) -> &'static str {
|
||||||
partial_type_name(std::any::type_name::<Self>(), last)
|
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,
|
BaseModule,
|
||||||
ModuleTrait,
|
ModuleTrait,
|
||||||
};
|
};
|
||||||
|
mod extension;
|
||||||
|
pub use extension::{
|
||||||
|
BaseExtension,
|
||||||
|
ExtensionTrait,
|
||||||
|
};
|
||||||
|
|
||||||
pub(crate) mod all;
|
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::html::{Markup, html};
|
||||||
use crate::core::response::page::PageAssets;
|
use crate::core::response::page::PageAssets;
|
||||||
use crate::util::partial_type_name;
|
use crate::util;
|
||||||
|
|
||||||
pub use std::any::Any as AnyComponent;
|
pub use std::any::Any as AnyComponent;
|
||||||
|
|
||||||
|
|
@ -9,7 +9,7 @@ pub trait BaseComponent {
|
||||||
|
|
||||||
fn single_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ComponentTrait: AnyComponent + BaseComponent + Send + Sync {
|
pub trait ComponentTrait: AnyComponent + BaseComponent + Send + Sync {
|
||||||
|
|
@ -52,11 +52,11 @@ impl<C: ?Sized + ComponentTrait> BaseComponent for C {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn single_name(&self) -> &'static str {
|
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 {
|
fn qualified_name(&self, last: u8) -> &'static str {
|
||||||
partial_type_name(std::any::type_name::<Self>(), last)
|
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::html::{Markup, html};
|
||||||
use crate::core::response::page::{ComponentTrait, Favicon, Page, PageAssets};
|
use crate::core::response::page::{ComponentTrait, Favicon, Page, PageAssets};
|
||||||
use crate::base::component::Chunck;
|
use crate::base::component::Chunck;
|
||||||
use crate::util::partial_type_name;
|
use crate::util;
|
||||||
|
|
||||||
pub trait BaseTheme {
|
pub trait BaseTheme {
|
||||||
fn type_name(&self) -> &'static str;
|
fn type_name(&self) -> &'static str;
|
||||||
|
|
||||||
fn single_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".
|
/// Los temas deben implementar este "trait".
|
||||||
|
|
@ -143,10 +143,10 @@ impl<T: ?Sized + ThemeTrait> BaseTheme for T {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn single_name(&self) -> &'static str {
|
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 {
|
fn qualified_name(&self, last: u8) -> &'static str {
|
||||||
partial_type_name(std::any::type_name::<Self>(), last)
|
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 {
|
if last == 0 {
|
||||||
return type_name;
|
return type_name;
|
||||||
}
|
}
|
||||||
let positions: Vec<_> = type_name.rmatch_indices("::").collect();
|
let positions: Vec<_> = type_name.rmatch_indices("::").collect();
|
||||||
|
let last: usize = last as usize;
|
||||||
if positions.len() < last {
|
if positions.len() < last {
|
||||||
return type_name;
|
return type_name;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue