Modifica la definición de apps como un módulo más

This commit is contained in:
Manuel Cillero 2022-08-03 23:52:37 +02:00
parent 61813a44e5
commit 5c65642ec0
13 changed files with 384 additions and 137 deletions

View file

@ -13,9 +13,6 @@ pub mod locale;
#[cfg(feature = "database")]
pub mod db;
mod definition;
pub use definition::AppTrait;
pub mod application;
pub mod fatal_error;

View file

@ -1,11 +1,13 @@
use super::{fatal_error::FatalError, AppTrait};
use super::fatal_error::FatalError;
use crate::config::SETTINGS;
use crate::core::module::ModuleStaticRef;
use crate::core::{module, theme};
use crate::html::Markup;
use crate::response::page::ResultPage;
use crate::{base, trace, LazyStatic};
use crate::LazyStatic;
use actix_web::dev::Server;
use std::io::Error;
pub struct Application {
@ -13,7 +15,7 @@ pub struct Application {
}
impl Application {
pub async fn prepare(app: impl AppTrait) -> Result<Self, Error> {
pub async fn prepare(app: ModuleStaticRef) -> Result<Self, Error> {
// Rótulo de presentación.
super::banner::print_on_startup();
@ -23,40 +25,25 @@ impl Application {
// Valida el identificador de idioma.
LazyStatic::force(&super::locale::LANGID);
// Conecta con la base de datos (opcional).
#[cfg(feature = "database")]
// Conecta con la base de datos.
LazyStatic::force(&super::db::DBCONN);
// Deshabilita los módulos indicados por la aplicación.
module::all::disable_modules(app.disable_modules());
// Habilita los módulos predeterminados.
module::all::enable_modules(vec![&base::module::homepage::DefaultHomePage]);
// Habilita los módulos de la aplicación.
module::all::enable_modules(app.enable_modules());
// Registra los módulos de la aplicación.
module::all::register_modules(app);
// Registra los temas predeterminados.
theme::all::register_themes(vec![
&base::theme::aliner::Aliner,
&base::theme::minimal::Minimal,
&base::theme::bootsier::Bootsier,
&base::theme::bulmix::Bulmix,
]);
// Registra los temas de la aplicación.
theme::all::register_themes(app.themes());
// Registra los temas de los módulos.
module::all::register_themes();
// Registra las acciones de todos los módulos.
// Registra acciones de los módulos.
module::all::register_actions();
// Ejecuta actualizaciones pendientes de la base de datos (opcional).
#[cfg(feature = "database")]
module::all::run_migrations();
// Inicializa los módulos que lo requieran.
// Inicializa los módulos.
module::all::init_modules();
// Ejecuta la función de inicio de la aplicación.
trace::info!("Calling application bootstrap");
app.bootstrap();
#[cfg(feature = "database")]
// Ejecuta actualizaciones pendientes de la base de datos.
module::all::run_migrations();
// Prepara el servidor web.
let server = super::HttpServer::new(move || {

View file

@ -1,18 +0,0 @@
use crate::core::module::ModuleStaticRef;
use crate::core::theme::ThemeStaticRef;
pub trait AppTrait: Send + Sync {
fn bootstrap(&self) {}
fn enable_modules(&self) -> Vec<ModuleStaticRef> {
vec![]
}
fn disable_modules(&self) -> Vec<ModuleStaticRef> {
vec![]
}
fn themes(&self) -> Vec<ThemeStaticRef> {
vec![]
}
}

View file

@ -1,5 +1,6 @@
use super::ModuleStaticRef;
use crate::core::hook::add_action;
use crate::core::theme;
use crate::{app, trace, LazyStatic};
#[cfg(feature = "database")]
@ -7,47 +8,42 @@ use crate::{db::*, run_now};
use std::sync::RwLock;
// DISABLED MODULES ********************************************************************************
static DISABLED_MODULES: LazyStatic<RwLock<Vec<ModuleStaticRef>>> =
LazyStatic::new(|| RwLock::new(Vec::new()));
pub fn disable_modules(modules: Vec<ModuleStaticRef>) {
let mut disabled_modules = DISABLED_MODULES.write().unwrap();
for module in modules {
if !disabled_modules
.iter()
.any(|m| m.handler() == module.handler())
{
trace::debug!("Disabling the \"{}\" module", module.single_name());
disabled_modules.push(module);
}
}
}
// ENABLED MODULES *********************************************************************************
// REGISTER MODULES ********************************************************************************
static ENABLED_MODULES: LazyStatic<RwLock<Vec<ModuleStaticRef>>> =
LazyStatic::new(|| RwLock::new(Vec::new()));
pub fn enable_modules(modules: Vec<ModuleStaticRef>) {
for module in modules {
let mut list: Vec<ModuleStaticRef> = Vec::new();
add_to_enabled(&mut list, module);
list.reverse();
ENABLED_MODULES.write().unwrap().append(&mut list);
static DISCARDED_MODULES: LazyStatic<RwLock<Vec<ModuleStaticRef>>> =
LazyStatic::new(|| RwLock::new(Vec::new()));
pub fn register_modules(app: ModuleStaticRef) {
// Revisa los módulos a deshabilitar.
let mut list: Vec<ModuleStaticRef> = Vec::new();
add_to_discarded(&mut list, app);
DISCARDED_MODULES.write().unwrap().append(&mut list);
// Habilita los módulos de la aplicación.
let mut list: Vec<ModuleStaticRef> = Vec::new();
add_to_enabled(&mut list, app);
list.reverse();
ENABLED_MODULES.write().unwrap().append(&mut list);
}
fn add_to_discarded(list: &mut Vec<ModuleStaticRef>, module: ModuleStaticRef) {
for u in module.uninstall_modules().iter() {
if !list.iter().any(|m| m.handler() == u.handler()) {
list.push(*u);
trace::debug!("Module \"{}\" discarded", u.single_name());
}
}
for d in module.dependencies().iter() {
add_to_discarded(list, *d);
}
}
fn add_to_enabled(list: &mut Vec<ModuleStaticRef>, module: ModuleStaticRef) {
if !ENABLED_MODULES
.read()
.unwrap()
.iter()
.any(|m| m.handler() == module.handler())
&& !list.iter().any(|m| m.handler() == module.handler())
{
if DISABLED_MODULES
if !list.iter().any(|m| m.handler() == module.handler()) {
if DISCARDED_MODULES
.read()
.unwrap()
.iter()
@ -58,7 +54,6 @@ fn add_to_enabled(list: &mut Vec<ModuleStaticRef>, module: ModuleStaticRef) {
module.single_name()
);
} else {
trace::debug!("Enabling the \"{}\" module", module.single_name());
list.push(module);
let mut dependencies = module.dependencies();
@ -66,23 +61,21 @@ fn add_to_enabled(list: &mut Vec<ModuleStaticRef>, module: ModuleStaticRef) {
for d in dependencies.iter() {
add_to_enabled(list, *d);
}
trace::debug!("Enabling \"{}\" module", module.single_name());
}
}
}
// CONFIGURE MODULES *******************************************************************************
// REGISTER THEMES *********************************************************************************
pub fn init_modules() {
pub fn register_themes() {
for m in ENABLED_MODULES.read().unwrap().iter() {
m.init_module();
theme::all::register_themes(m.themes());
}
}
pub fn configure_services(cfg: &mut app::web::ServiceConfig) {
for m in ENABLED_MODULES.read().unwrap().iter() {
m.configure_service(cfg);
}
}
// REGISTER ACTIONS ********************************************************************************
pub fn register_actions() {
for m in ENABLED_MODULES.read().unwrap().iter() {
@ -92,23 +85,10 @@ pub fn register_actions() {
}
}
#[cfg(feature = "database")]
pub(crate) fn run_migrations() {
run_now({
struct Migrator;
impl MigratorTrait for Migrator {
fn migrations() -> Vec<MigrationItem> {
let mut migrations = vec![];
for m in DISABLED_MODULES.read().unwrap().iter() {
migrations.append(&mut m.migrations());
}
migrations
}
}
Migrator::down(&app::db::DBCONN, None)
})
.unwrap();
// RUN MIGRATIONS **********************************************************************************
#[cfg(feature = "database")]
pub fn run_migrations() {
run_now({
struct Migrator;
impl MigratorTrait for Migrator {
@ -123,4 +103,36 @@ pub(crate) fn run_migrations() {
Migrator::up(&app::db::DBCONN, None)
})
.unwrap();
run_now({
struct Migrator;
impl MigratorTrait for Migrator {
fn migrations() -> Vec<MigrationItem> {
let mut migrations = vec![];
for m in DISCARDED_MODULES.read().unwrap().iter() {
migrations.append(&mut m.migrations());
}
migrations
}
}
Migrator::down(&app::db::DBCONN, None)
})
.unwrap();
}
// INIT MODULES ************************************************************************************
pub fn init_modules() {
trace::info!("Calling application bootstrap");
for m in ENABLED_MODULES.read().unwrap().iter() {
m.init();
}
}
// CONFIGURE SERVICES ******************************************************************************
pub fn configure_services(cfg: &mut app::web::ServiceConfig) {
for m in ENABLED_MODULES.read().unwrap().iter() {
m.configure_service(cfg);
}
}

View file

@ -1,5 +1,6 @@
use crate::app;
use crate::core::hook::HookAction;
use crate::core::theme::ThemeStaticRef;
use crate::util::{single_type_name, Handler};
#[cfg(feature = "database")]
@ -27,10 +28,13 @@ pub trait ModuleTrait: BaseModule + Send + Sync {
vec![]
}
fn init_module(&self) {}
fn uninstall_modules(&self) -> Vec<ModuleStaticRef> {
vec![]
}
#[allow(unused_variables)]
fn configure_service(&self, cfg: &mut app::web::ServiceConfig) {}
fn themes(&self) -> Vec<ThemeStaticRef> {
vec![]
}
fn actions(&self) -> Vec<HookAction> {
vec![]
@ -41,6 +45,11 @@ pub trait ModuleTrait: BaseModule + Send + Sync {
fn migrations(&self) -> Vec<MigrationItem> {
vec![]
}
fn init(&self) {}
#[allow(unused_variables)]
fn configure_service(&self, cfg: &mut app::web::ServiceConfig) {}
}
impl<M: ?Sized + ModuleTrait> BaseModule for M {

View file

@ -1,13 +1,19 @@
use super::ThemeStaticRef;
use crate::{app, theme_static_files, trace, LazyStatic};
use crate::{app, base, theme_static_files, trace, LazyStatic};
use std::sync::RwLock;
include!(concat!(env!("OUT_DIR"), "/theme.rs"));
// Temas registrados.
static THEMES: LazyStatic<RwLock<Vec<ThemeStaticRef>>> =
LazyStatic::new(|| RwLock::new(Vec::new()));
static THEMES: LazyStatic<RwLock<Vec<ThemeStaticRef>>> = LazyStatic::new(|| {
RwLock::new(vec![
&base::theme::aliner::Aliner,
&base::theme::minimal::Minimal,
&base::theme::bootsier::Bootsier,
&base::theme::bulmix::Bulmix,
])
});
pub fn register_themes(themes: Vec<ThemeStaticRef>) {
let mut registered_themes = THEMES.write().unwrap();

View file

@ -19,12 +19,13 @@ pub use crate::{db, db::*, migration_item, pub_migration};
pub use crate::app;
pub use crate::app::application::Application;
pub use crate::app::fatal_error::FatalError;
pub use crate::app::{AppTrait, HttpMessage};
pub use crate::app::HttpMessage;
pub use crate::core::{component::*, hook::*, module::*, theme::*};
pub use crate::{hook_action, hook_before_render_component};
pub use crate::response::page::*;
pub use crate::response::ResponseError;
pub use crate::base::component::*;