🔥 Refactor TypeId/Any use, drop own Handle

This commit is contained in:
Manuel Cillero 2024-02-16 17:00:34 +01:00
parent 8402b7946e
commit 169e562488
59 changed files with 137 additions and 289 deletions

View file

@ -1,6 +1,5 @@
use pagetop::prelude::*;
#[derive(AssignHandle)]
struct Drust;
impl PackageTrait for Drust {

View file

@ -1,6 +1,5 @@
use pagetop::prelude::*;
#[derive(AssignHandle)]
struct HelloName;
impl PackageTrait for HelloName {

View file

@ -1,6 +1,5 @@
use pagetop::prelude::*;
#[derive(AssignHandle)]
struct HelloWorld;
impl PackageTrait for HelloWorld {

View file

@ -2,9 +2,8 @@ mod maud;
use concat_string::concat_string;
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use proc_macro_error::proc_macro_error;
use quote::{format_ident, quote, quote_spanned, ToTokens};
use quote::{quote, quote_spanned, ToTokens};
use syn::{parse_macro_input, parse_str, DeriveInput, ItemFn};
#[proc_macro]
@ -103,48 +102,6 @@ pub fn test(_: TokenStream, item: TokenStream) -> TokenStream {
output
}
#[proc_macro_derive(AssignHandle, attributes(handle))]
pub fn assign_handle_derive(input: TokenStream) -> TokenStream {
impl_handle(input, quote! { pagetop })
}
#[proc_macro_derive(BaseHandle, attributes(handle))]
pub fn base_handle_derive(input: TokenStream) -> TokenStream {
impl_handle(input, quote! { crate })
}
fn impl_handle(input: TokenStream, crate_name: TokenStream2) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let name = &input.ident;
let handle_name = format_ident!("HANDLE_{}", name.to_string().to_uppercase());
let expanded = quote! {
const #handle_name: #crate_name::Handle =
#crate_name::util::handle(module_path!(), file!(), line!(), column!());
impl #impl_generics #crate_name::ImplementHandle for #name #ty_generics #where_clause {
#[inline]
fn static_handle() -> #crate_name::Handle {
#handle_name
}
#[inline]
fn matches_handle(is: #crate_name::Handle) -> bool {
is == #handle_name
}
#[inline]
fn handle(&self) -> #crate_name::Handle {
#handle_name
}
}
};
TokenStream::from(expanded)
}
#[proc_macro_derive(ComponentClasses)]
pub fn component_classes_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);

View file

@ -4,7 +4,6 @@ static_locales!(LOCALES_ADMIN);
mod summary;
#[derive(AssignHandle)]
pub struct Admin;
impl PackageTrait for Admin {

View file

@ -4,7 +4,6 @@ static_locales!(LOCALES_BOOTSIER);
static_files!(bootsier);
#[derive(AssignHandle)]
pub struct Bootsier;
impl PackageTrait for Bootsier {
@ -81,8 +80,8 @@ impl ThemeTrait for Bootsier {
}
fn before_prepare_component(&self, component: &mut dyn ComponentTrait, _cx: &mut Context) {
match component.handle() {
h if Icon::matches_handle(h) => {
match component.type_id() {
t if t == TypeId::of::<Icon>() => {
if let Some(i) = component_as_mut::<Icon>(component) {
match i.font_size() {
FontSize::ExtraLarge => {
@ -104,7 +103,7 @@ impl ThemeTrait for Bootsier {
};
}
}
h if Button::matches_handle(h) => {
t if t == TypeId::of::<Button>() => {
if let Some(b) = component_as_mut::<Button>(component) {
match b.style() {
ButtonStyle::Default => {
@ -152,7 +151,7 @@ impl ThemeTrait for Bootsier {
};
}
}
h if Heading::matches_handle(h) => {
t if t == TypeId::of::<Heading>() => {
if let Some(h) = component_as_mut::<Heading>(component) {
match h.size() {
HeadingSize::ExtraLarge => {
@ -174,7 +173,7 @@ impl ThemeTrait for Bootsier {
};
}
}
h if Paragraph::matches_handle(h) => {
t if t == TypeId::of::<Paragraph>() => {
if let Some(p) = component_as_mut::<Paragraph>(component) {
match p.font_size() {
FontSize::ExtraLarge => {
@ -201,8 +200,8 @@ impl ThemeTrait for Bootsier {
}
fn render_component(&self, component: &dyn ComponentTrait, cx: &mut Context) -> Option<Markup> {
match component.handle() {
h if Error404::matches_handle(h) => Some(html! {
match component.type_id() {
t if t == TypeId::of::<Error404>() => Some(html! {
div class="jumbotron" {
div class="media" {
img

View file

@ -2,7 +2,6 @@ use pagetop::prelude::*;
static_files!(bulmix);
#[derive(AssignHandle)]
pub struct Bulmix;
impl PackageTrait for Bulmix {
@ -30,8 +29,8 @@ impl ThemeTrait for Bulmix {
}
fn before_prepare_component(&self, component: &mut dyn ComponentTrait, _cx: &mut Context) {
match component.handle() {
h if Icon::matches_handle(h) => {
match component.type_id() {
t if t == TypeId::of::<Icon>() => {
if let Some(i) = component_as_mut::<Icon>(component) {
match i.font_size() {
FontSize::ExtraLarge => {
@ -53,7 +52,7 @@ impl ThemeTrait for Bulmix {
};
}
}
h if Button::matches_handle(h) => {
t if t == TypeId::of::<Button>() => {
if let Some(b) = component_as_mut::<Button>(component) {
match b.style() {
ButtonStyle::Default => {
@ -101,7 +100,7 @@ impl ThemeTrait for Bulmix {
};
}
}
h if Heading::matches_handle(h) => {
t if t == TypeId::of::<Heading>() => {
if let Some(h) = component_as_mut::<Heading>(component) {
match h.size() {
HeadingSize::Subtitle => {
@ -111,7 +110,7 @@ impl ThemeTrait for Bulmix {
};
}
}
h if Paragraph::matches_handle(h) => {
t if t == TypeId::of::<Paragraph>() => {
if let Some(p) = component_as_mut::<Paragraph>(component) {
p.add_classes("block");
match p.font_size() {
@ -143,8 +142,8 @@ impl ThemeTrait for Bulmix {
component: &dyn ComponentTrait,
_cx: &mut Context,
) -> Option<Markup> {
match component.handle() {
h if Icon::matches_handle(h) => {
match component.type_id() {
t if t == TypeId::of::<Icon>() => {
if let Some(i) = component_as_ref::<Icon>(component) {
return match i.icon_name().get() {
None => None,

View file

@ -4,7 +4,6 @@ static_locales!(LOCALES_HOMEDEMO);
static_files!(homedemo);
#[derive(AssignHandle)]
pub struct HomeDemo;
impl PackageTrait for HomeDemo {

View file

@ -5,7 +5,6 @@ static_locales!(LOCALES_NODE);
//mod entity;
mod migration;
#[derive(AssignHandle)]
pub struct Node;
impl PackageTrait for Node {

View file

@ -4,7 +4,6 @@ static_locales!(LOCALES_USER);
mod migration;
#[derive(AssignHandle)]
pub struct User;
impl PackageTrait for User {

View file

@ -1,19 +1,17 @@
use crate::prelude::*;
use crate::BaseHandle;
use super::FnActionComponent;
#[derive(BaseHandle)]
pub struct AfterPrepareComponent<C: ComponentTrait> {
f: FnActionComponent<C>,
referer_handle: Option<Handle>,
referer_type_id: Option<TypeId>,
referer_id: OptionId,
weight: Weight,
}
impl<C: ComponentTrait> ActionTrait for AfterPrepareComponent<C> {
fn referer_handle(&self) -> Option<Handle> {
self.referer_handle
fn referer_type_id(&self) -> Option<TypeId> {
self.referer_type_id
}
fn referer_id(&self) -> Option<String> {
@ -29,7 +27,7 @@ impl<C: ComponentTrait> AfterPrepareComponent<C> {
pub fn new(f: FnActionComponent<C>) -> Self {
AfterPrepareComponent {
f,
referer_handle: Some(C::static_handle()),
referer_type_id: Some(TypeId::of::<C>()),
referer_id: OptionId::default(),
weight: 0,
}
@ -48,7 +46,7 @@ impl<C: ComponentTrait> AfterPrepareComponent<C> {
#[inline(always)]
pub(crate) fn dispatch(component: &mut C, cx: &mut Context, referer_id: Option<String>) {
dispatch_actions(
(Self::static_handle(), Some(component.handle()), referer_id),
(TypeId::of::<Self>(), Some(TypeId::of::<C>()), referer_id),
|action| (action_ref::<AfterPrepareComponent<C>>(&**action).f)(component, cx),
);
}

View file

@ -1,19 +1,17 @@
use crate::prelude::*;
use crate::BaseHandle;
use super::FnActionComponent;
#[derive(BaseHandle)]
pub struct BeforePrepareComponent<C: ComponentTrait> {
f: FnActionComponent<C>,
referer_handle: Option<Handle>,
referer_type_id: Option<TypeId>,
referer_id: OptionId,
weight: Weight,
}
impl<C: ComponentTrait> ActionTrait for BeforePrepareComponent<C> {
fn referer_handle(&self) -> Option<Handle> {
self.referer_handle
fn referer_type_id(&self) -> Option<TypeId> {
self.referer_type_id
}
fn referer_id(&self) -> Option<String> {
@ -29,7 +27,7 @@ impl<C: ComponentTrait> BeforePrepareComponent<C> {
pub fn new(f: FnActionComponent<C>) -> Self {
BeforePrepareComponent {
f,
referer_handle: Some(C::static_handle()),
referer_type_id: Some(TypeId::of::<C>()),
referer_id: OptionId::default(),
weight: 0,
}
@ -48,7 +46,7 @@ impl<C: ComponentTrait> BeforePrepareComponent<C> {
#[inline(always)]
pub(crate) fn dispatch(component: &mut C, cx: &mut Context, referer_id: Option<String>) {
dispatch_actions(
(Self::static_handle(), Some(component.handle()), referer_id),
(TypeId::of::<Self>(), Some(TypeId::of::<C>()), referer_id),
|action| (action_ref::<BeforePrepareComponent<C>>(&**action).f)(component, cx),
);
}

View file

@ -1,9 +1,7 @@
use crate::prelude::*;
use crate::BaseHandle;
use super::FnActionPage;
#[derive(BaseHandle)]
pub struct AfterPrepareBody {
f: FnActionPage,
weight: Weight,
@ -27,7 +25,7 @@ impl AfterPrepareBody {
#[inline(always)]
pub(crate) fn dispatch(page: &mut Page) {
dispatch_actions((Self::static_handle(), None, None), |action| {
dispatch_actions((TypeId::of::<Self>(), None, None), |action| {
(action_ref::<AfterPrepareBody>(&**action).f)(page)
});
}

View file

@ -1,9 +1,7 @@
use crate::prelude::*;
use crate::BaseHandle;
use super::FnActionPage;
#[derive(BaseHandle)]
pub struct BeforePrepareBody {
f: FnActionPage,
weight: Weight,
@ -27,7 +25,7 @@ impl BeforePrepareBody {
#[inline(always)]
pub(crate) fn dispatch(page: &mut Page) {
dispatch_actions((Self::static_handle(), None, None), |action| {
dispatch_actions((TypeId::of::<Self>(), None, None), |action| {
(action_ref::<BeforePrepareBody>(&**action).f)(page)
});
}

View file

@ -1,8 +1,7 @@
use crate::prelude::*;
use crate::BaseHandle;
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct Block {
id : OptionId,
weight : Weight,

View file

@ -1,8 +1,7 @@
use crate::prelude::*;
use crate::BaseHandle;
#[rustfmt::skip]
#[derive(BaseHandle, SmartDefault)]
#[derive(SmartDefault)]
pub struct Branding {
id : OptionId,
weight : Weight,

View file

@ -1,5 +1,4 @@
use crate::prelude::*;
use crate::BaseHandle;
#[derive(SmartDefault)]
pub enum ButtonTarget {
@ -12,7 +11,7 @@ pub enum ButtonTarget {
}
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct Button {
id : OptionId,
weight : Weight,

View file

@ -1,8 +1,6 @@
use crate::core::component::{ComponentTrait, Context};
use crate::html::{html, PrepareMarkup};
use crate::BaseHandle;
#[derive(BaseHandle)]
pub struct Error403;
impl ComponentTrait for Error403 {

View file

@ -1,8 +1,6 @@
use crate::core::component::{ComponentTrait, Context};
use crate::html::{html, PrepareMarkup};
use crate::BaseHandle;
#[derive(BaseHandle)]
pub struct Error404;
impl ComponentTrait for Error404 {

View file

@ -1,8 +1,7 @@
use crate::prelude::*;
use crate::BaseHandle;
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct Container {
id : OptionId,
weight : Weight,

View file

@ -1,8 +1,7 @@
use crate::prelude::*;
use crate::BaseHandle;
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct Item {
id : OptionId,
weight : Weight,

View file

@ -1,5 +1,4 @@
use crate::prelude::*;
use crate::BaseHandle;
#[derive(SmartDefault)]
pub enum ActionButtonType {
@ -19,7 +18,7 @@ impl ToString for ActionButtonType {
}
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct ActionButton {
weight : Weight,
renderable : Renderable,

View file

@ -1,8 +1,7 @@
use crate::prelude::*;
use crate::BaseHandle;
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct Date {
weight : Weight,
renderable : Renderable,

View file

@ -1,5 +1,4 @@
use crate::prelude::*;
use crate::BaseHandle;
#[derive(SmartDefault)]
pub enum FormMethod {
@ -9,7 +8,7 @@ pub enum FormMethod {
}
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct Form {
id : OptionId,
weight : Weight,

View file

@ -1,8 +1,7 @@
use crate::prelude::*;
use crate::BaseHandle;
#[rustfmt::skip]
#[derive(BaseHandle, SmartDefault)]
#[derive(SmartDefault)]
pub struct Hidden {
weight: Weight,
name : OptionName,

View file

@ -1,5 +1,4 @@
use crate::prelude::*;
use crate::BaseHandle;
#[derive(SmartDefault)]
pub enum InputType {
@ -13,7 +12,7 @@ pub enum InputType {
}
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct Input {
weight : Weight,
renderable : Renderable,

View file

@ -1,5 +1,4 @@
use crate::prelude::*;
use crate::BaseHandle;
#[derive(SmartDefault)]
pub enum HeadingType {
@ -40,7 +39,7 @@ impl ToString for HeadingSize {
}
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct Heading {
id : OptionId,
weight : Weight,

View file

@ -1,7 +1,6 @@
use crate::prelude::*;
use crate::BaseHandle;
#[derive(BaseHandle, SmartDefault)]
#[derive(SmartDefault)]
pub struct Html(Markup);
impl ComponentTrait for Html {

View file

@ -1,8 +1,7 @@
use crate::prelude::*;
use crate::BaseHandle;
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct Icon {
weight : Weight,
renderable: Renderable,

View file

@ -1,5 +1,4 @@
use crate::prelude::*;
use crate::BaseHandle;
const IMG_FLUID: &str = "pt-img__fluid";
const IMG_FIXED: &str = "pt-img__fixed";
@ -15,7 +14,7 @@ pub enum ImageSize {
}
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct Image {
id : OptionId,
weight : Weight,

View file

@ -1,5 +1,4 @@
use crate::prelude::*;
use crate::BaseHandle;
use super::Submenu;
@ -17,7 +16,7 @@ pub enum ElementType {
// Element.
#[rustfmt::skip]
#[derive(BaseHandle, SmartDefault)]
#[derive(SmartDefault)]
pub struct Element {
weight : Weight,
renderable : Renderable,

View file

@ -1,10 +1,9 @@
use crate::prelude::*;
use crate::BaseHandle;
use super::Element;
#[rustfmt::skip]
#[derive(BaseHandle, SmartDefault)]
#[derive(SmartDefault)]
pub struct Group {
id : OptionId,
weight : Weight,

View file

@ -1,5 +1,4 @@
use crate::prelude::*;
use crate::BaseHandle;
use super::{Megamenu, Submenu};
@ -23,7 +22,7 @@ pub enum ItemType {
// Item.
#[rustfmt::skip]
#[derive(BaseHandle, SmartDefault)]
#[derive(SmartDefault)]
pub struct Item {
weight : Weight,
renderable : Renderable,

View file

@ -1,10 +1,9 @@
use crate::prelude::*;
use crate::BaseHandle;
use super::Group;
#[rustfmt::skip]
#[derive(BaseHandle, SmartDefault)]
#[derive(SmartDefault)]
pub struct Megamenu {
id : OptionId,
weight : Weight,

View file

@ -1,10 +1,9 @@
use crate::prelude::*;
use crate::BaseHandle;
use super::Item;
#[rustfmt::skip]
#[derive(BaseHandle, SmartDefault)]
#[derive(SmartDefault)]
pub struct Menu {
id : OptionId,
weight : Weight,

View file

@ -1,10 +1,9 @@
use crate::prelude::*;
use crate::BaseHandle;
use super::Item;
#[rustfmt::skip]
#[derive(BaseHandle, SmartDefault)]
#[derive(SmartDefault)]
pub struct Submenu {
id : OptionId,
weight : Weight,

View file

@ -1,8 +1,7 @@
use crate::prelude::*;
use crate::BaseHandle;
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct Paragraph {
id : OptionId,
weight : Weight,

View file

@ -1,5 +1,4 @@
use crate::prelude::*;
use crate::BaseHandle;
#[derive(Default, Eq, PartialEq)]
pub enum PoweredByLogo {
@ -12,7 +11,7 @@ pub enum PoweredByLogo {
}
#[rustfmt::skip]
#[derive(BaseHandle, SmartDefault)]
#[derive(SmartDefault)]
pub struct PoweredBy {
weight : Weight,
renderable: Renderable,

View file

@ -1,7 +1,6 @@
use crate::prelude::*;
use crate::BaseHandle;
#[derive(BaseHandle, SmartDefault)]
#[derive(SmartDefault)]
pub struct Translate(L10n);
impl ComponentTrait for Translate {

View file

@ -1,5 +1,4 @@
use crate::prelude::*;
use crate::BaseHandle;
#[derive(SmartDefault)]
pub enum WrapperType {
@ -12,7 +11,7 @@ pub enum WrapperType {
}
#[rustfmt::skip]
#[derive(BaseHandle, ComponentClasses, SmartDefault)]
#[derive(ComponentClasses, SmartDefault)]
pub struct Wrapper {
id : OptionId,
weight : Weight,

View file

@ -1,7 +1,5 @@
use crate::prelude::*;
use crate::BaseHandle;
#[derive(BaseHandle)]
pub struct Basic;
impl PackageTrait for Basic {

View file

@ -1,7 +1,5 @@
use crate::prelude::*;
use crate::BaseHandle;
#[derive(BaseHandle)]
pub struct Chassis;
impl PackageTrait for Chassis {

View file

@ -1,7 +1,5 @@
use crate::prelude::*;
use crate::BaseHandle;
#[derive(BaseHandle)]
pub struct Inception;
impl PackageTrait for Inception {

View file

@ -1,5 +1,32 @@
//! Key types and functions for creating actions, components, packages, and themes.
use crate::util;
use std::any::Any;
// Common definitions for core types.
pub trait AnyBase: Any {
fn single_name(&self) -> &'static str;
fn as_any_ref(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
}
impl<T: Any> AnyBase for T {
fn single_name(&self) -> &'static str {
util::single_type_name::<Self>()
}
fn as_any_ref(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
}
// API to define functions that alter the behavior of PageTop core.
pub mod action;

View file

@ -1,5 +1,5 @@
mod definition;
pub use definition::{action_ref, ActionBase, ActionTrait};
pub use definition::{action_ref, ActionTrait};
mod list;
pub use list::Action;

View file

@ -1,10 +1,10 @@
use crate::core::action::{Action, ActionsList};
use crate::{Handle, LazyStatic};
use crate::{LazyStatic, TypeId};
use std::collections::HashMap;
use std::sync::RwLock;
pub type KeyAction = (Handle, Option<Handle>, Option<String>);
pub type KeyAction = (TypeId, Option<TypeId>, Option<String>);
// Registered actions.
static ACTIONS: LazyStatic<RwLock<HashMap<KeyAction, ActionsList>>> =
@ -13,8 +13,8 @@ static ACTIONS: LazyStatic<RwLock<HashMap<KeyAction, ActionsList>>> =
pub fn add_action(action: Action) {
let mut actions = ACTIONS.write().unwrap();
let key_action = (
action.handle(),
action.referer_handle(),
action.type_id(),
action.referer_type_id(),
action.referer_id(),
);
if let Some(list) = actions.get_mut(&key_action) {

View file

@ -1,13 +1,8 @@
use crate::{Handle, ImplementHandle, Weight};
use crate::core::AnyBase;
use crate::{TypeId, Weight};
use std::any::Any;
pub trait ActionBase: Any {
fn as_ref_any(&self) -> &dyn Any;
}
pub trait ActionTrait: ActionBase + ImplementHandle + Send + Sync {
fn referer_handle(&self) -> Option<Handle> {
pub trait ActionTrait: AnyBase + Send + Sync {
fn referer_type_id(&self) -> Option<TypeId> {
None
}
@ -20,12 +15,6 @@ pub trait ActionTrait: ActionBase + ImplementHandle + Send + Sync {
}
}
impl<C: ActionTrait> ActionBase for C {
fn as_ref_any(&self) -> &dyn Any {
self
}
}
pub fn action_ref<A: 'static>(action: &dyn ActionTrait) -> &A {
action.as_ref_any().downcast_ref::<A>().unwrap()
action.as_any_ref().downcast_ref::<A>().unwrap()
}

View file

@ -1,6 +1,6 @@
use crate::core::component::{ComponentTrait, Context};
use crate::html::{html, Markup};
use crate::{fn_with, Handle, Weight};
use crate::{fn_with, TypeId, Weight};
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
@ -36,8 +36,8 @@ impl ArcAnyComponent {
// ArcAnyComponent HELPERS.
fn handle(&self) -> Handle {
self.0.read().unwrap().handle()
fn type_id(&self) -> TypeId {
self.0.read().unwrap().type_id()
}
fn id(&self) -> String {
@ -126,8 +126,8 @@ impl AnyComponents {
self.0.iter().filter(move |&c| c.id() == id)
}
pub fn iter_by_handle(&self, handle: Handle) -> impl Iterator<Item = &ArcAnyComponent> {
self.0.iter().filter(move |&c| c.handle() == handle)
pub fn iter_by_type_id(&self, type_id: TypeId) -> impl Iterator<Item = &ArcAnyComponent> {
self.0.iter().filter(move |&c| c.type_id() == type_id)
}
// AnyComponents RENDER.

View file

@ -1,6 +1,6 @@
use crate::core::component::{ComponentTrait, Context};
use crate::html::{html, Markup};
use crate::{fn_with, Handle, Weight};
use crate::{fn_with, TypeId, Weight};
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
@ -41,8 +41,8 @@ impl<C: ComponentTrait> ArcTypedComponent<C> {
// ArcTypedComponent HELPERS.
fn handle(&self) -> Handle {
self.0.read().unwrap().handle()
fn type_id(&self) -> TypeId {
self.0.read().unwrap().type_id()
}
fn id(&self) -> String {
@ -123,8 +123,8 @@ impl<C: ComponentTrait + Default> TypedComponents<C> {
self.0.iter().filter(move |&c| c.id() == id)
}
pub fn iter_by_handle(&self, handle: Handle) -> impl Iterator<Item = &ArcTypedComponent<C>> {
self.0.iter().filter(move |&c| c.handle() == handle)
pub fn iter_by_type_id(&self, type_id: TypeId) -> impl Iterator<Item = &ArcTypedComponent<C>> {
self.0.iter().filter(move |&c| c.type_id() == type_id)
}
// TypedComponents RENDER.

View file

@ -1,19 +1,14 @@
use crate::base::action;
use crate::core::component::Context;
use crate::core::AnyBase;
use crate::html::{html, Markup, PrepareMarkup};
use crate::{util, ImplementHandle, Weight};
use crate::{util, Weight};
use std::any::Any;
pub trait ComponentBase: Any {
pub trait ComponentBase {
fn render(&mut self, cx: &mut Context) -> Markup;
fn as_ref_any(&self) -> &dyn Any;
fn as_mut_any(&mut self) -> &mut dyn Any;
}
pub trait ComponentTrait: ComponentBase + ImplementHandle + Send + Sync {
pub trait ComponentTrait: AnyBase + ComponentBase + Send + Sync {
fn new() -> Self
where
Self: Sized;
@ -87,20 +82,12 @@ impl<C: ComponentTrait> ComponentBase for C {
html! {}
}
}
fn as_ref_any(&self) -> &dyn Any {
self
}
fn as_mut_any(&mut self) -> &mut dyn Any {
self
}
}
pub fn component_as_ref<C: ComponentTrait>(component: &dyn ComponentTrait) -> Option<&C> {
component.as_ref_any().downcast_ref::<C>()
component.as_any_ref().downcast_ref::<C>()
}
pub fn component_as_mut<C: ComponentTrait>(component: &mut dyn ComponentTrait) -> Option<&mut C> {
component.as_mut_any().downcast_mut::<C>()
component.as_any_mut().downcast_mut::<C>()
}

View file

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

View file

@ -43,7 +43,7 @@ pub fn register_packages(app: PackageRef) {
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()) {
if !list.iter().any(|p| p.type_id() == d.type_id()) {
list.push(*d);
trace::debug!("Package \"{}\" dropped", d.single_name());
}
@ -54,12 +54,12 @@ fn add_to_dropped(list: &mut Vec<PackageRef>, package: PackageRef) {
}
fn add_to_enabled(list: &mut Vec<PackageRef>, package: PackageRef) {
if !list.iter().any(|p| p.handle() == package.handle()) {
if !list.iter().any(|p| p.type_id() == package.type_id()) {
if DROPPED_PACKAGES
.read()
.unwrap()
.iter()
.any(|p| p.handle() == package.handle())
.any(|p| p.type_id() == package.type_id())
{
panic!(
"Trying to enable \"{}\" package which is dropped",
@ -78,7 +78,7 @@ fn add_to_enabled(list: &mut Vec<PackageRef>, package: PackageRef) {
let mut registered_themes = THEMES.write().unwrap();
if !registered_themes
.iter()
.any(|t| t.handle() == theme.handle())
.any(|t| t.type_id() == theme.type_id())
{
registered_themes.push(theme);
trace::debug!("Enabling \"{}\" theme", theme.single_name());

View file

@ -1,19 +1,16 @@
use crate::core::action::Action;
use crate::core::theme::ThemeRef;
use crate::core::AnyBase;
use crate::locale::L10n;
use crate::{actions, service, util, ImplementHandle};
use crate::{actions, service};
#[cfg(feature = "database")]
use crate::{db::MigrationItem, migrations};
pub type PackageRef = &'static dyn PackageTrait;
pub trait PackageBase {
fn single_name(&self) -> &'static str;
}
/// Los paquetes deben implementar este *trait*.
pub trait PackageTrait: ImplementHandle + PackageBase + Send + Sync {
pub trait PackageTrait: AnyBase + Send + Sync {
fn name(&self) -> L10n {
L10n::n(self.single_name())
}
@ -41,7 +38,6 @@ pub trait PackageTrait: ImplementHandle + PackageBase + Send + Sync {
fn init(&self) {}
#[cfg(feature = "database")]
#[allow(unused_variables)]
fn migrations(&self) -> Vec<MigrationItem> {
migrations![]
}
@ -49,9 +45,3 @@ pub trait PackageTrait: ImplementHandle + PackageBase + Send + Sync {
#[allow(unused_variables)]
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {}
}
impl<M: ?Sized + PackageTrait> PackageBase for M {
fn single_name(&self) -> &'static str {
util::single_type_name::<Self>()
}
}

View file

@ -118,10 +118,11 @@ pub trait ThemeTrait: PackageTrait + Send + Sync {
/*
Cómo usarlo:
match component.handle() {
BLOCK_COMPONENT => {
let block = component_as_mut::<Block>(component);
block.alter_title("New title");
match component.type_id() {
t if t == TypeId::of::<Block>() => {
if let Some(b) = component_as_mut::<Block>(component) {
b.alter_title("New title");
}
},
_ => {},
}
@ -138,10 +139,11 @@ pub trait ThemeTrait: PackageTrait + Send + Sync {
/*
Cómo usarlo:
match component.handle() {
BLOCK_COMPONENT => {
let block = component_as_mut::<Block>(component);
block.alter_title("New title");
match component.type_id() {
t if t == TypeId::of::<Block>() => {
if let Some(b) = component_as_mut::<Block>(component) {
b.alter_title("New title");
}
},
_ => {},
}
@ -159,13 +161,9 @@ pub trait ThemeTrait: PackageTrait + Send + Sync {
/*
Cómo usarlo:
match component.handle() {
BLOCK_COMPONENT => {
let block = component_as_ref::<Block>(component);
match block.template() {
"default" => Some(block_default(block)),
_ => None,
}
match component.type_id() {
t if t == TypeId::of::<Block>() => {
Some(block_default(block))
},
_ => None,
}

View file

@ -1,11 +1,11 @@
use crate::core::component::{AnyComponents, ArcAnyComponent, ArcAnyOp};
use crate::core::theme::ThemeRef;
use crate::{Handle, LazyStatic, SmartDefault};
use crate::{LazyStatic, SmartDefault, TypeId};
use std::collections::HashMap;
use std::sync::RwLock;
static THEME_REGIONS: LazyStatic<RwLock<HashMap<Handle, ComponentsInRegions>>> =
static THEME_REGIONS: LazyStatic<RwLock<HashMap<TypeId, ComponentsInRegions>>> =
LazyStatic::new(|| RwLock::new(HashMap::new()));
static COMMON_REGIONS: LazyStatic<RwLock<ComponentsInRegions>> =
@ -31,7 +31,7 @@ impl ComponentsInRegions {
pub fn get_components(&self, theme: ThemeRef, region: &str) -> AnyComponents {
let common = COMMON_REGIONS.read().unwrap();
if let Some(r) = THEME_REGIONS.read().unwrap().get(&theme.handle()) {
if let Some(r) = THEME_REGIONS.read().unwrap().get(&theme.type_id()) {
AnyComponents::merge(&[common.0.get(region), self.0.get(region), r.0.get(region)])
} else {
AnyComponents::merge(&[common.0.get(region), self.0.get(region)])
@ -51,10 +51,10 @@ pub fn add_component_in(region: Region, arc: ArcAnyComponent) {
}
Region::OfTheme(theme, region) => {
let mut regions = THEME_REGIONS.write().unwrap();
if let Some(r) = regions.get_mut(&theme.handle()) {
if let Some(r) = regions.get_mut(&theme.type_id()) {
r.add_component_in(region, arc);
} else {
regions.insert(theme.handle(), ComponentsInRegions::new(region, arc));
regions.insert(theme.type_id(), ComponentsInRegions::new(region, arc));
}
}
}

View file

@ -32,7 +32,6 @@
//! ```rust
//! use pagetop::prelude::*;
//!
//! #[derive(AssignHandle)]
//! struct HelloWorld;
//!
//! impl PackageTrait for HelloWorld {
@ -85,9 +84,7 @@ pub use paste::paste;
/// Custom derive for automatically implementing the [Default] trait with customized default values.
pub use smart_default::SmartDefault;
pub use pagetop_macros::{fn_with, main, test, AssignHandle, ComponentClasses};
pub(crate) use pagetop_macros::BaseHandle;
pub use pagetop_macros::{fn_with, main, test, ComponentClasses};
// *************************************************************************************************
// GLOBAL.
@ -96,19 +93,7 @@ pub(crate) use pagetop_macros::BaseHandle;
pub use once_cell::sync::Lazy as LazyStatic;
pub use static_files::Resource as StaticResource;
pub type Handle = u64;
pub trait ImplementHandle {
fn static_handle() -> Handle
where
Self: Sized;
fn matches_handle(is: Handle) -> bool
where
Self: Sized;
fn handle(&self) -> Handle;
}
pub use std::any::TypeId;
pub type Weight = i8;

View file

@ -4,11 +4,11 @@
pub use crate::{concat_string, fn_with, html, main, paste, test, SmartDefault};
// Global.
pub use crate::{Handle, HashMapResources, ImplementHandle, LazyStatic, Weight};
pub use crate::{HashMapResources, LazyStatic, TypeId, Weight};
// Functions and macro helpers.
pub use crate::util;
pub use crate::{kv, AssignHandle, ComponentClasses};
pub use crate::{kv, ComponentClasses};
// MACROS.
@ -39,6 +39,8 @@ pub use crate::{db, db::*, migrations, new_migration};
pub use crate::service;
pub use crate::service::HttpMessage;
pub use crate::core::AnyBase;
pub use crate::core::action::*;
pub use crate::core::component::*;
pub use crate::core::package::*;

View file

@ -1,6 +1,6 @@
//! Functions and macro helpers.
use crate::{trace, Handle};
use crate::trace;
use std::io;
use std::path::PathBuf;
@ -9,41 +9,6 @@ use std::path::PathBuf;
// FUNCTIONS HELPERS.
// *************************************************************************************************
// https://stackoverflow.com/a/71464396
#[doc(hidden)]
pub const fn handle(
module_path: &'static str,
file: &'static str,
line: u32,
column: u32,
) -> Handle {
let mut hash = 0xcbf29ce484222325;
let prime = 0x00000100000001B3;
let mut bytes = module_path.as_bytes();
let mut i = 0;
while i < bytes.len() {
hash ^= bytes[i] as u64;
hash = hash.wrapping_mul(prime);
i += 1;
}
bytes = file.as_bytes();
i = 0;
while i < bytes.len() {
hash ^= bytes[i] as u64;
hash = hash.wrapping_mul(prime);
i += 1;
}
hash ^= line as u64;
hash = hash.wrapping_mul(prime);
hash ^= column as u64;
hash = hash.wrapping_mul(prime);
hash
}
pub fn partial_type_name(type_name: &'static str, last: usize) -> &'static str {
if last == 0 {
return type_name;

View file

@ -1,6 +1,5 @@
use pagetop::prelude::*;
#[derive(AssignHandle)]
struct HealthCheck;
impl PackageTrait for HealthCheck {}