🚚 Refactor modules to packages to avoid Rust clash

This commit is contained in:
Manuel Cillero 2024-01-07 00:18:54 +01:00
parent 98fa367ebc
commit 89f78a1aff
35 changed files with 125 additions and 123 deletions

View file

@ -5,14 +5,14 @@ members = [
# Utilities.
"pagetop-macros",
"pagetop-build",
"pagetop-homedemo",
# Modules.
"pagetop-admin",
"pagetop-user",
"pagetop-node",
# Themes.
"pagetop-bootsier",
"pagetop-bulmix",
# Packages.
"pagetop-homedemo",
"pagetop-admin",
"pagetop-user",
"pagetop-node",
]
exclude = [
@ -20,3 +20,5 @@ exclude = [
"examples",
"tests",
]
resolver = "2"

View file

@ -3,13 +3,13 @@ use pagetop::prelude::*;
#[derive(AssignHandle)]
struct Drust;
impl ModuleTrait for Drust {
fn dependencies(&self) -> Vec<ModuleRef> {
impl PackageTrait for Drust {
fn dependencies(&self) -> Vec<PackageRef> {
vec![
// Themes.
&pagetop_bootsier::Bootsier,
&pagetop_bulmix::Bulmix,
// Modules.
// Packages.
&pagetop_homedemo::HomeDemo,
&pagetop_admin::Admin,
&pagetop_user::User,
@ -17,7 +17,7 @@ impl ModuleTrait for Drust {
]
}
fn drop_modules(&self) -> Vec<ModuleRef> {
fn drop_packages(&self) -> Vec<PackageRef> {
vec![
// &pagetop_node::Node
]

View file

@ -3,7 +3,7 @@ use pagetop::prelude::*;
#[derive(AssignHandle)]
struct HelloName;
impl ModuleTrait for HelloName {
impl PackageTrait for HelloName {
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
scfg.service(hello_name);
}

View file

@ -3,7 +3,7 @@ use pagetop::prelude::*;
#[derive(AssignHandle)]
struct HelloWorld;
impl ModuleTrait for HelloWorld {
impl PackageTrait for HelloWorld {
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
scfg.route("/", service::web::get().to(hello_world));
}

View file

@ -7,13 +7,13 @@ mod summary;
#[derive(AssignHandle)]
pub struct Admin;
impl ModuleTrait for Admin {
impl PackageTrait for Admin {
fn name(&self) -> L10n {
L10n::t("module_name", &LOCALES_ADMIN)
L10n::t("package_name", &LOCALES_ADMIN)
}
fn description(&self) -> L10n {
L10n::t("module_description", &LOCALES_ADMIN)
L10n::t("package_description", &LOCALES_ADMIN)
}
fn actions(&self) -> Vec<Action> {

View file

@ -1,2 +1,2 @@
module_name = Admin module
module_description = Administration module.
package_name = Admin module
package_description = Administration module.

View file

@ -1,2 +1,2 @@
module_name = Admin module
module_description = Módulo de administración.
package_name = Admin module
package_description = Módulo de administración.

View file

@ -5,7 +5,7 @@ use pagetop::prelude::*;
pub async fn summary(request: service::HttpRequest) -> ResultPage<Markup, ErrorPage> {
let top_menu = Menu::new()
.with_id("admin-menu-test")
.add_item(menu::Item::label(L10n::t("module_name", &LOCALES_ADMIN)))
.add_item(menu::Item::label(L10n::t("package_name", &LOCALES_ADMIN)))
.add_item(menu::Item::label(L10n::n("Ejemplo \"Label\"")))
.add_item(menu::Item::link(L10n::n("Ejemplo \"Link\""), |_| {
"https://www.google.es"

View file

@ -7,7 +7,7 @@ static_files!(bootsier);
#[derive(AssignHandle)]
pub struct Bootsier;
impl ModuleTrait for Bootsier {
impl PackageTrait for Bootsier {
fn theme(&self) -> Option<ThemeRef> {
Some(&Bootsier)
}

View file

@ -5,7 +5,7 @@ static_files!(bulmix);
#[derive(AssignHandle)]
pub struct Bulmix;
impl ModuleTrait for Bulmix {
impl PackageTrait for Bulmix {
fn theme(&self) -> Option<ThemeRef> {
Some(&Bulmix)
}

View file

@ -7,13 +7,13 @@ static_files!(homedemo);
#[derive(AssignHandle)]
pub struct HomeDemo;
impl ModuleTrait for HomeDemo {
impl PackageTrait for HomeDemo {
fn name(&self) -> L10n {
L10n::t("module_name", &LOCALES_HOMEDEMO)
L10n::t("package_name", &LOCALES_HOMEDEMO)
}
fn description(&self) -> L10n {
L10n::t("module_description", &LOCALES_HOMEDEMO)
L10n::t("package_description", &LOCALES_HOMEDEMO)
}
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {

View file

@ -1,5 +1,5 @@
module_name = Default homepage
module_description = Displays a demo homepage when none is configured.
package_name = Default homepage
package_description = Displays a demo homepage when none is configured.
page_title = Hello world!

View file

@ -1,5 +1,5 @@
module_name = Página de inicio predeterminada
module_description = Muestra una página de demostración predeterminada cuando no hay ninguna configurada.
package_name = Página de inicio predeterminada
package_description = Muestra una página de demostración predeterminada cuando no hay ninguna configurada.
page_title = ¡Hola mundo!

View file

@ -8,13 +8,13 @@ mod migration;
#[derive(AssignHandle)]
pub struct Node;
impl ModuleTrait for Node {
impl PackageTrait for Node {
fn name(&self) -> L10n {
L10n::t("module_name", &LOCALES_NODE)
L10n::t("package_name", &LOCALES_NODE)
}
fn description(&self) -> L10n {
L10n::t("module_description", &LOCALES_NODE)
L10n::t("package_description", &LOCALES_NODE)
}
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {

View file

@ -1,2 +1,2 @@
module_name = Node
module_description = Allows content to be submitted to the site and displayed on pages.
package_name = Node
package_description = Allows content to be submitted to the site and displayed on pages.

View file

@ -1,2 +1,2 @@
module_name = Nodo
module_description = Permite enviar contenidos al sitio y mostrarlos en páginas.
package_name = Nodo
package_description = Permite enviar contenidos al sitio y mostrarlos en páginas.

View file

@ -7,13 +7,13 @@ mod migration;
#[derive(AssignHandle)]
pub struct User;
impl ModuleTrait for User {
impl PackageTrait for User {
fn name(&self) -> L10n {
L10n::t("module_name", &LOCALES_USER)
L10n::t("package_name", &LOCALES_USER)
}
fn description(&self) -> L10n {
L10n::t("module_description", &LOCALES_USER)
L10n::t("package_description", &LOCALES_USER)
}
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {

View file

@ -1,5 +1,5 @@
module_name = User
module_description = Manages the user registration and login system.
package_name = User
package_description = Manages the user registration and login system.
username = User name
password = Password

View file

@ -1,5 +1,5 @@
module_name = Usuario
module_description = Gestiona el registro de usuarios y el sistema de accesos.
package_name = Usuario
package_description = Gestiona el registro de usuarios y el sistema de accesos.
username = Nombre de usuario
password = Contraseña

View file

@ -2,7 +2,7 @@
mod figfont;
use crate::core::{module, module::ModuleRef};
use crate::core::{package, package::PackageRef};
use crate::html::Markup;
use crate::response::page::{ErrorPage, ResultPage};
use crate::{concat_string, config, locale, service, trace, LazyStatic};
@ -21,7 +21,7 @@ use std::io::Error;
pub struct Application;
impl Application {
pub fn prepare(app: ModuleRef) -> Result<Self, Error> {
pub fn prepare(app: PackageRef) -> Result<Self, Error> {
// On startup.
show_banner();
@ -35,18 +35,18 @@ impl Application {
// Conecta con la base de datos.
LazyStatic::force(&db::DBCONN);
// Registra los módulos de la aplicación.
module::all::register_modules(app);
// Registra los paquetes de la aplicación.
package::all::register_packages(app);
// Registra acciones de los módulos.
module::all::register_actions();
// Registra acciones de los paquetes.
package::all::register_actions();
// Inicializa los módulos.
module::all::init_modules();
// Inicializa los paquetes.
package::all::init_packages();
#[cfg(feature = "database")]
// Ejecuta actualizaciones pendientes de la base de datos.
module::all::run_migrations();
package::all::run_migrations();
Ok(Self)
}
@ -107,7 +107,7 @@ fn service_app() -> service::App<
>,
> {
service::App::new()
.configure(module::all::configure_services)
.configure(package::all::configure_services)
.default_service(service::web::route().to(service_not_found))
}

View file

@ -1,4 +1,4 @@
//! Base actions, components, modules, and themes.
//! Base actions, components, packages, and themes.
pub mod action;

View file

@ -4,7 +4,7 @@ use crate::BaseHandle;
#[derive(BaseHandle)]
pub struct Basic;
impl ModuleTrait for Basic {
impl PackageTrait for Basic {
fn name(&self) -> L10n {
L10n::n("Basic")
}

View file

@ -4,7 +4,7 @@ use crate::BaseHandle;
#[derive(BaseHandle)]
pub struct Chassis;
impl ModuleTrait for Chassis {
impl PackageTrait for Chassis {
fn name(&self) -> L10n {
L10n::n("Chassis")
}

View file

@ -4,7 +4,7 @@ use crate::BaseHandle;
#[derive(BaseHandle)]
pub struct Inception;
impl ModuleTrait for Inception {
impl PackageTrait for Inception {
fn name(&self) -> L10n {
L10n::n("Inception")
}

View file

@ -105,7 +105,7 @@
//! println!("Value of PAGETOP_RUN_MODE: {}", &config::SETTINGS.app.run_mode);
//! }
//!
//! fn module_settings() {
//! fn package_settings() {
//! println!("{} - {:?}", &SETTINGS.myapp.name, &SETTINGS.myapp.description);
//! println!("{}", &SETTINGS.myapp.width);
//! }

View file

@ -1,4 +1,4 @@
//! Key types and functions for creating actions, components, modules, and themes.
//! Key types and functions for creating actions, components, packages, and themes.
// API to define functions that alter the behavior of PageTop core.
pub mod action;
@ -6,8 +6,8 @@ pub mod action;
// API to build new components.
pub mod component;
// API to add new features with modules.
pub mod module;
// API to add new features with packages.
pub mod package;
// API to add new layouts with themes.
pub mod theme;

View file

@ -1,4 +0,0 @@
mod definition;
pub use definition::{ModuleBase, ModuleRef, ModuleTrait};
pub(crate) mod all;

View file

@ -0,0 +1,4 @@
mod definition;
pub use definition::{PackageBase, PackageRef, PackageTrait};
pub(crate) mod all;

View file

@ -1,5 +1,5 @@
use crate::core::action::add_action;
use crate::core::module::ModuleRef;
use crate::core::package::PackageRef;
use crate::core::theme::all::THEMES;
use crate::{config, service, service_for_static_files, static_files, trace, LazyStatic};
@ -10,71 +10,71 @@ use std::sync::RwLock;
static_files!(base);
// MODULES *****************************************************************************************
// PACKAGES ****************************************************************************************
static ENABLED_MODULES: LazyStatic<RwLock<Vec<ModuleRef>>> =
static ENABLED_PACKAGES: LazyStatic<RwLock<Vec<PackageRef>>> =
LazyStatic::new(|| RwLock::new(Vec::new()));
static DROPPED_MODULES: LazyStatic<RwLock<Vec<ModuleRef>>> =
static DROPPED_PACKAGES: LazyStatic<RwLock<Vec<PackageRef>>> =
LazyStatic::new(|| RwLock::new(Vec::new()));
// REGISTER MODULES ********************************************************************************
// REGISTER PACKAGES *******************************************************************************
pub fn register_modules(app: ModuleRef) {
// List of modules to drop.
let mut list: Vec<ModuleRef> = Vec::new();
pub fn register_packages(app: PackageRef) {
// List of packages to drop.
let mut list: Vec<PackageRef> = Vec::new();
add_to_dropped(&mut list, app);
DROPPED_MODULES.write().unwrap().append(&mut list);
DROPPED_PACKAGES.write().unwrap().append(&mut list);
// List of modules to enable.
let mut list: Vec<ModuleRef> = Vec::new();
// List of packages to enable.
let mut list: Vec<PackageRef> = Vec::new();
// Enable default themes.
add_to_enabled(&mut list, &crate::base::theme::Basic);
add_to_enabled(&mut list, &crate::base::theme::Chassis);
add_to_enabled(&mut list, &crate::base::theme::Inception);
// Enable application modules.
// Enable application packages.
add_to_enabled(&mut list, app);
list.reverse();
ENABLED_MODULES.write().unwrap().append(&mut list);
ENABLED_PACKAGES.write().unwrap().append(&mut list);
}
fn add_to_dropped(list: &mut Vec<ModuleRef>, module: ModuleRef) {
for d in module.drop_modules().iter() {
if !list.iter().any(|m| m.handle() == d.handle()) {
fn add_to_dropped(list: &mut Vec<PackageRef>, package: PackageRef) {
for d in package.drop_packages().iter() {
if !list.iter().any(|p| p.handle() == d.handle()) {
list.push(*d);
trace::debug!("Module \"{}\" dropped", d.single_name());
trace::debug!("Package \"{}\" dropped", d.single_name());
}
}
for d in module.dependencies().iter() {
for d in package.dependencies().iter() {
add_to_dropped(list, *d);
}
}
fn add_to_enabled(list: &mut Vec<ModuleRef>, module: ModuleRef) {
if !list.iter().any(|m| m.handle() == module.handle()) {
if DROPPED_MODULES
fn add_to_enabled(list: &mut Vec<PackageRef>, package: PackageRef) {
if !list.iter().any(|p| p.handle() == package.handle()) {
if DROPPED_PACKAGES
.read()
.unwrap()
.iter()
.any(|m| m.handle() == module.handle())
.any(|p| p.handle() == package.handle())
{
panic!(
"Trying to enable \"{}\" module which is dropped",
module.single_name()
"Trying to enable \"{}\" package which is dropped",
package.single_name()
);
} else {
list.push(module);
list.push(package);
let mut dependencies = module.dependencies();
let mut dependencies = package.dependencies();
dependencies.reverse();
for d in dependencies.iter() {
add_to_enabled(list, *d);
}
if let Some(theme) = module.theme() {
if let Some(theme) = package.theme() {
let mut registered_themes = THEMES.write().unwrap();
if !registered_themes
.iter()
@ -84,7 +84,7 @@ fn add_to_enabled(list: &mut Vec<ModuleRef>, module: ModuleRef) {
trace::debug!("Enabling \"{}\" theme", theme.single_name());
}
} else {
trace::debug!("Enabling \"{}\" module", module.single_name());
trace::debug!("Enabling \"{}\" package", package.single_name());
}
}
}
@ -93,18 +93,18 @@ fn add_to_enabled(list: &mut Vec<ModuleRef>, module: ModuleRef) {
// REGISTER ACTIONS ********************************************************************************
pub fn register_actions() {
for m in ENABLED_MODULES.read().unwrap().iter() {
for m in ENABLED_PACKAGES.read().unwrap().iter() {
for a in m.actions().into_iter() {
add_action(a);
}
}
}
// INIT MODULES ************************************************************************************
// INIT PACKAGES ***********************************************************************************
pub fn init_modules() {
pub fn init_packages() {
trace::info!("Calling application bootstrap");
for m in ENABLED_MODULES.read().unwrap().iter() {
for m in ENABLED_PACKAGES.read().unwrap().iter() {
m.init();
}
}
@ -119,7 +119,7 @@ pub fn run_migrations() {
impl MigratorTrait for Migrator {
fn migrations() -> Vec<MigrationItem> {
let mut migrations = vec![];
for m in ENABLED_MODULES.read().unwrap().iter() {
for m in ENABLED_PACKAGES.read().unwrap().iter() {
migrations.append(&mut m.migrations());
}
migrations
@ -135,7 +135,7 @@ pub fn run_migrations() {
impl MigratorTrait for Migrator {
fn migrations() -> Vec<MigrationItem> {
let mut migrations = vec![];
for m in DROPPED_MODULES.read().unwrap().iter() {
for m in DROPPED_PACKAGES.read().unwrap().iter() {
migrations.append(&mut m.migrations());
}
migrations
@ -156,7 +156,7 @@ pub fn configure_services(scfg: &mut service::web::ServiceConfig) {
base => "/base",
[&config::SETTINGS.dev.pagetop_project_dir, "pagetop/static/base"]
);
for m in ENABLED_MODULES.read().unwrap().iter() {
for m in ENABLED_PACKAGES.read().unwrap().iter() {
m.configure_service(scfg);
}
}

View file

@ -6,14 +6,14 @@ use crate::{actions, service, util, ImplementHandle};
#[cfg(feature = "database")]
use crate::{db::MigrationItem, migrations};
pub type ModuleRef = &'static dyn ModuleTrait;
pub type PackageRef = &'static dyn PackageTrait;
pub trait ModuleBase {
pub trait PackageBase {
fn single_name(&self) -> &'static str;
}
/// Los módulos deben implementar este *trait*.
pub trait ModuleTrait: ImplementHandle + ModuleBase + Send + Sync {
/// Los paquetes deben implementar este *trait*.
pub trait PackageTrait: ImplementHandle + PackageBase + Send + Sync {
fn name(&self) -> L10n {
L10n::n(self.single_name())
}
@ -26,11 +26,11 @@ pub trait ModuleTrait: ImplementHandle + ModuleBase + Send + Sync {
None
}
fn dependencies(&self) -> Vec<ModuleRef> {
fn dependencies(&self) -> Vec<PackageRef> {
vec![]
}
fn drop_modules(&self) -> Vec<ModuleRef> {
fn drop_packages(&self) -> Vec<PackageRef> {
vec![]
}
@ -50,7 +50,7 @@ pub trait ModuleTrait: ImplementHandle + ModuleBase + Send + Sync {
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {}
}
impl<M: ?Sized + ModuleTrait> ModuleBase for M {
impl<M: ?Sized + PackageTrait> PackageBase for M {
fn single_name(&self) -> &'static str {
util::single_type_name::<Self>()
}

View file

@ -1,5 +1,5 @@
use crate::core::component::{ComponentTrait, Context};
use crate::core::module::ModuleTrait;
use crate::core::package::PackageTrait;
use crate::html::{html, Favicon, Markup, OptionId};
use crate::locale::L10n;
use crate::response::page::Page;
@ -8,7 +8,7 @@ use crate::{concat_string, config};
pub type ThemeRef = &'static dyn ThemeTrait;
/// Los temas deben implementar este "trait".
pub trait ThemeTrait: ModuleTrait + Send + Sync {
pub trait ThemeTrait: PackageTrait + Send + Sync {
#[rustfmt::skip]
fn regions(&self) -> Vec<(&'static str, L10n)> {
vec![

View file

@ -28,11 +28,11 @@
//!
//! * Essential web framework ([`service`]).
//!
//! * Key types and functions for creating actions, components, modules, and themes ([`core`]).
//! * Key types and functions for creating actions, components, packages, and themes ([`core`]).
//!
//! * Web request response variants ([`response`]).
//!
//! * Base actions, components, modules, and themes ([`base`]).
//! * Base actions, components, packages, and themes ([`base`]).
//!
//! * Utility functions ([`util`]).
//!
@ -49,7 +49,7 @@
//! #[derive(AssignHandle)]
//! struct HelloWorld;
//!
//! impl ModuleTrait for HelloWorld {
//! impl PackageTrait for HelloWorld {
//! fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {
//! scfg.route("/", service::web::get().to(hello_world));
//! }
@ -66,7 +66,7 @@
//! Application::prepare(&HelloWorld).unwrap().run()?.await
//! }
//! ```
//! This program implements a module named `HelloWorld` with one service that returns a web page
//! This program implements a package named `HelloWorld` with one service that returns a web page
//! that greets the world whenever it is accessed from the browser at `http://localhost:8088` (using
//! the [default configuration settings](`config::Server`)). You can find this code in the PageTop
//! [basic examples repository](https://github.com/manuelcillero/pagetop/tree/main/examples/basics).
@ -74,15 +74,15 @@
//! # 🧱 Extending PageTop
//!
//! The PageTop core API provides a comprehensive toolkit for extending its functionalities to
//! specific requirements and application scenarios through actions, components, modules, and
//! specific requirements and application scenarios through actions, components, packages, and
//! themes:
//!
//! * **Actions** serve as a mechanism to customize PageTop's internal behavior by intercepting its
//! execution flow.
//! * **Components** encapsulate HTML, CSS, and JavaScript into functional, configurable, and
//! well-defined units.
//! * **Modules** extend or customize existing functionality by interacting with PageTop APIs or
//! third-party module APIs.
//! * **Packages** extend or customize existing functionality by interacting with PageTop APIs or
//! third-party package APIs.
//! * **Themes** enable developers to alter the appearance of pages and components without affecting
//! their functionality.
//!
@ -91,8 +91,8 @@
//! Projects leveraging PageTop will use `cargo` to resolve dependencies, similar to any other Rust
//! project.
//!
//! Nevertheless, its crucial that each module explicitly declares its
//! [dependencies](core::module::ModuleTrait#method.dependencies), if any, to assist PageTop in
//! Nevertheless, its crucial that each package explicitly declares its
//! [dependencies](core::package::PackageTrait#method.dependencies), if any, to assist PageTop in
//! structuring and initializing the application in a modular fashion.
#![cfg_attr(docsrs, feature(doc_cfg))]
@ -167,13 +167,13 @@ pub mod db;
// Essential web framework.
pub mod service;
// Key types and functions for creating actions, components, modules, and themes.
// Key types and functions for creating actions, components, packages, and themes.
pub mod core;
// Web request response variants.
pub mod response;
// Base actions, components, modules, and themes.
// Base actions, components, packages, and themes.
pub mod base;
// Prepare and run the application.

View file

@ -41,7 +41,7 @@ pub use crate::service::HttpMessage;
pub use crate::core::action::*;
pub use crate::core::component::*;
pub use crate::core::module::*;
pub use crate::core::package::*;
pub use crate::core::theme::*;
pub use crate::response::{page::*, redirect::*, ResponseError};

View file

@ -160,7 +160,7 @@ impl Page {
// Theme actions before preparing the page body.
self.context.theme().before_prepare_body(self);
// Module actions before preparing the page body.
// Packages actions before preparing the page body.
action::page::BeforePrepareBody::dispatch(self);
// Prepare page body.
@ -169,7 +169,7 @@ impl Page {
// Theme actions after preparing the page body.
self.context.theme().after_prepare_body(self);
// Module actions after preparing the page body.
// Packages actions after preparing the page body.
action::page::AfterPrepareBody::dispatch(self);
// Prepare page head.

View file

@ -3,7 +3,7 @@ use pagetop::prelude::*;
#[derive(AssignHandle)]
struct HealthCheck;
impl ModuleTrait for HealthCheck {}
impl PackageTrait for HealthCheck {}
#[pagetop::test]
async fn health_check_works() {