🎨 Improve registering packages
This commit is contained in:
parent
ddd27fd2a6
commit
3827c859e9
5 changed files with 52 additions and 22 deletions
12
src/core.rs
12
src/core.rs
|
|
@ -4,14 +4,18 @@ use crate::util::TypeInfo;
|
|||
|
||||
use std::any::Any;
|
||||
|
||||
// Common definitions for core types.
|
||||
/// A base trait that extends `Any` to provide metadata and dynamic type casting capabilities.
|
||||
pub trait AnyBase: Any {
|
||||
/// Returns the full name of the type.
|
||||
fn type_name(&self) -> &'static str;
|
||||
|
||||
/// Returns a short name for the type.
|
||||
fn short_name(&self) -> &'static str;
|
||||
|
||||
/// Returns a reference to `dyn Any` for dynamic type casting.
|
||||
fn as_any_ref(&self) -> &dyn Any;
|
||||
|
||||
/// Returns a mutable reference to `dyn Any` for dynamic type casting.
|
||||
fn as_any_mut(&mut self) -> &mut dyn Any;
|
||||
}
|
||||
|
||||
|
|
@ -38,7 +42,9 @@ impl<T: Any> AnyBase for T {
|
|||
}
|
||||
}
|
||||
|
||||
/// A trait for advanced dynamic type manipulation and downcasting.
|
||||
pub trait AnyTo: AnyBase {
|
||||
/// Checks if the type is of the specified type `T`.
|
||||
#[inline]
|
||||
fn is<T>(&self) -> bool
|
||||
where
|
||||
|
|
@ -47,6 +53,7 @@ pub trait AnyTo: AnyBase {
|
|||
self.as_any_ref().is::<T>()
|
||||
}
|
||||
|
||||
/// Attempts to downcast a reference to the specified type `T`.
|
||||
#[inline]
|
||||
fn downcast_ref<T>(&self) -> Option<&T>
|
||||
where
|
||||
|
|
@ -55,6 +62,7 @@ pub trait AnyTo: AnyBase {
|
|||
self.as_any_ref().downcast_ref()
|
||||
}
|
||||
|
||||
/// Attempts to downcast a mutable reference to the specified type `T`.
|
||||
#[inline]
|
||||
fn downcast_mut<T>(&mut self) -> Option<&mut T>
|
||||
where
|
||||
|
|
@ -66,7 +74,7 @@ pub trait AnyTo: AnyBase {
|
|||
|
||||
impl<T: ?Sized + AnyBase> AnyTo for T {}
|
||||
|
||||
// API to define functions that alter the behavior of PageTop core.
|
||||
// API to define functions that alter the predefined behavior of the code.
|
||||
pub mod action;
|
||||
|
||||
// API to build new components.
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ use crate::{global, include_files, include_files_service, service, trace};
|
|||
|
||||
use std::sync::{LazyLock, RwLock};
|
||||
|
||||
include_files!(assets);
|
||||
|
||||
// PACKAGES ****************************************************************************************
|
||||
|
||||
static ENABLED_PACKAGES: LazyLock<RwLock<Vec<PackageRef>>> =
|
||||
|
|
@ -24,15 +22,14 @@ pub fn register_packages(root_package: Option<PackageRef>) {
|
|||
// Add default theme to the enabled list.
|
||||
add_to_enabled(&mut enabled_list, &crate::base::theme::Basic);
|
||||
|
||||
// Add default welcome page package to the enabled list.
|
||||
add_to_enabled(&mut enabled_list, &crate::base::package::Welcome);
|
||||
|
||||
// If a root package is provided, add it to the enabled list.
|
||||
if let Some(package) = root_package {
|
||||
add_to_enabled(&mut enabled_list, package);
|
||||
}
|
||||
// Reverse the order to ensure packages are sorted from none to most dependencies.
|
||||
enabled_list.reverse();
|
||||
|
||||
// Add default welcome page package to the enabled list.
|
||||
add_to_enabled(&mut enabled_list, &crate::base::package::Welcome);
|
||||
|
||||
// Save the final list of enabled packages.
|
||||
ENABLED_PACKAGES.write().unwrap().append(&mut enabled_list);
|
||||
|
||||
|
|
@ -49,16 +46,14 @@ pub fn register_packages(root_package: Option<PackageRef>) {
|
|||
fn add_to_enabled(list: &mut Vec<PackageRef>, package: PackageRef) {
|
||||
// Check if the package is not already in the enabled list to avoid duplicates.
|
||||
if !list.iter().any(|p| p.type_id() == package.type_id()) {
|
||||
// Add the package to the enabled list.
|
||||
list.push(package);
|
||||
|
||||
// Reverse dependencies to add them in correct order (dependencies first).
|
||||
let mut dependencies = package.dependencies();
|
||||
dependencies.reverse();
|
||||
for d in &dependencies {
|
||||
// Add the package dependencies in reverse order first.
|
||||
for d in package.dependencies().iter().rev() {
|
||||
add_to_enabled(list, *d);
|
||||
}
|
||||
|
||||
// Add the package itself to the enabled list.
|
||||
list.push(package);
|
||||
|
||||
// Check if the package has an associated theme to register.
|
||||
if let Some(theme) = package.theme() {
|
||||
let mut registered_themes = THEMES.write().unwrap();
|
||||
|
|
@ -127,6 +122,8 @@ pub fn init_packages() {
|
|||
|
||||
// CONFIGURE SERVICES ******************************************************************************
|
||||
|
||||
include_files!(assets);
|
||||
|
||||
pub fn configure_services(scfg: &mut service::web::ServiceConfig) {
|
||||
for m in ENABLED_PACKAGES.read().unwrap().iter() {
|
||||
m.configure_service(scfg);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ pub trait PackageTrait: AnyBase + Send + Sync {
|
|||
}
|
||||
|
||||
fn description(&self) -> L10n {
|
||||
L10n::none()
|
||||
L10n::default()
|
||||
}
|
||||
|
||||
fn theme(&self) -> Option<ThemeRef> {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ pub trait ThemeTrait: PackageTrait + Send + Sync {
|
|||
meta charset="utf-8";
|
||||
|
||||
@if let Some(title) = page.title() {
|
||||
title { (global::SETTINGS.app.name) (" - ") (title) }
|
||||
title { (global::SETTINGS.app.name) (" | ") (title) }
|
||||
} @else {
|
||||
title { (global::SETTINGS.app.name) }
|
||||
}
|
||||
|
|
@ -102,4 +102,33 @@ pub trait ThemeTrait: PackageTrait + Send + Sync {
|
|||
}
|
||||
})
|
||||
}
|
||||
/*
|
||||
fn prepare_page_body(&self, page: &mut Page) -> PrepareMarkup {
|
||||
PrepareMarkup::With(html! {
|
||||
body id=[page.body_id().get()] class=[page.body_classes().get()] {
|
||||
(page.body_content().render())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn error_403(&self, request: service::HttpRequest) -> Page {
|
||||
Page::new(request)
|
||||
.with_title(L10n::n("Error FORBIDDEN"))
|
||||
.with_body(PrepareMarkup::With(html! {
|
||||
div {
|
||||
h1 { ("FORBIDDEN ACCESS") }
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
fn error_404(&self, request: service::HttpRequest) -> Page {
|
||||
Page::new(request)
|
||||
.with_title(L10n::n("Error RESOURCE NOT FOUND"))
|
||||
.with_body(PrepareMarkup::With(html! {
|
||||
div {
|
||||
h1 { ("RESOURCE NOT FOUND") }
|
||||
}
|
||||
}))
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,10 +182,6 @@ pub struct L10n {
|
|||
}
|
||||
|
||||
impl L10n {
|
||||
pub fn none() -> Self {
|
||||
L10n::default()
|
||||
}
|
||||
|
||||
pub fn n(text: impl Into<String>) -> Self {
|
||||
L10n {
|
||||
op: L10nOp::Text(text.into()),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue