🔥 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::*; use pagetop::prelude::*;
#[derive(AssignHandle)]
struct Drust; struct Drust;
impl PackageTrait for Drust { impl PackageTrait for Drust {

View file

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

View file

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

View file

@ -2,9 +2,8 @@ mod maud;
use concat_string::concat_string; use concat_string::concat_string;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use proc_macro_error::proc_macro_error; 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}; use syn::{parse_macro_input, parse_str, DeriveInput, ItemFn};
#[proc_macro] #[proc_macro]
@ -103,48 +102,6 @@ pub fn test(_: TokenStream, item: TokenStream) -> TokenStream {
output 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)] #[proc_macro_derive(ComponentClasses)]
pub fn component_classes_derive(input: TokenStream) -> TokenStream { pub fn component_classes_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput); let input = parse_macro_input!(input as DeriveInput);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,5 +1,32 @@
//! Key types and functions for creating actions, components, packages, and themes. //! 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. // API to define functions that alter the behavior of PageTop core.
pub mod action; pub mod action;

View file

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

View file

@ -1,10 +1,10 @@
use crate::core::action::{Action, ActionsList}; use crate::core::action::{Action, ActionsList};
use crate::{Handle, LazyStatic}; use crate::{LazyStatic, TypeId};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::RwLock; use std::sync::RwLock;
pub type KeyAction = (Handle, Option<Handle>, Option<String>); pub type KeyAction = (TypeId, Option<TypeId>, Option<String>);
// Registered actions. // Registered actions.
static ACTIONS: LazyStatic<RwLock<HashMap<KeyAction, ActionsList>>> = static ACTIONS: LazyStatic<RwLock<HashMap<KeyAction, ActionsList>>> =
@ -13,8 +13,8 @@ static ACTIONS: LazyStatic<RwLock<HashMap<KeyAction, ActionsList>>> =
pub fn add_action(action: Action) { pub fn add_action(action: Action) {
let mut actions = ACTIONS.write().unwrap(); let mut actions = ACTIONS.write().unwrap();
let key_action = ( let key_action = (
action.handle(), action.type_id(),
action.referer_handle(), action.referer_type_id(),
action.referer_id(), action.referer_id(),
); );
if let Some(list) = actions.get_mut(&key_action) { 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 ActionTrait: AnyBase + Send + Sync {
fn referer_type_id(&self) -> Option<TypeId> {
pub trait ActionBase: Any {
fn as_ref_any(&self) -> &dyn Any;
}
pub trait ActionTrait: ActionBase + ImplementHandle + Send + Sync {
fn referer_handle(&self) -> Option<Handle> {
None 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 { 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::core::component::{ComponentTrait, Context};
use crate::html::{html, Markup}; use crate::html::{html, Markup};
use crate::{fn_with, Handle, Weight}; use crate::{fn_with, TypeId, Weight};
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
@ -36,8 +36,8 @@ impl ArcAnyComponent {
// ArcAnyComponent HELPERS. // ArcAnyComponent HELPERS.
fn handle(&self) -> Handle { fn type_id(&self) -> TypeId {
self.0.read().unwrap().handle() self.0.read().unwrap().type_id()
} }
fn id(&self) -> String { fn id(&self) -> String {
@ -126,8 +126,8 @@ impl AnyComponents {
self.0.iter().filter(move |&c| c.id() == id) self.0.iter().filter(move |&c| c.id() == id)
} }
pub fn iter_by_handle(&self, handle: Handle) -> impl Iterator<Item = &ArcAnyComponent> { pub fn iter_by_type_id(&self, type_id: TypeId) -> impl Iterator<Item = &ArcAnyComponent> {
self.0.iter().filter(move |&c| c.handle() == handle) self.0.iter().filter(move |&c| c.type_id() == type_id)
} }
// AnyComponents RENDER. // AnyComponents RENDER.

View file

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

View file

@ -1,19 +1,14 @@
use crate::base::action; use crate::base::action;
use crate::core::component::Context; use crate::core::component::Context;
use crate::core::AnyBase;
use crate::html::{html, Markup, PrepareMarkup}; use crate::html::{html, Markup, PrepareMarkup};
use crate::{util, ImplementHandle, Weight}; use crate::{util, Weight};
use std::any::Any; pub trait ComponentBase {
pub trait ComponentBase: Any {
fn render(&mut self, cx: &mut Context) -> Markup; 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 fn new() -> Self
where where
Self: Sized; Self: Sized;
@ -87,20 +82,12 @@ impl<C: ComponentTrait> ComponentBase for C {
html! {} 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> { 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> { 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; mod definition;
pub use definition::{PackageBase, PackageRef, PackageTrait}; pub use definition::{PackageRef, PackageTrait};
pub(crate) mod all; 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) { fn add_to_dropped(list: &mut Vec<PackageRef>, package: PackageRef) {
for d in package.drop_packages().iter() { 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); list.push(*d);
trace::debug!("Package \"{}\" dropped", d.single_name()); 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) { 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 if DROPPED_PACKAGES
.read() .read()
.unwrap() .unwrap()
.iter() .iter()
.any(|p| p.handle() == package.handle()) .any(|p| p.type_id() == package.type_id())
{ {
panic!( panic!(
"Trying to enable \"{}\" package which is dropped", "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(); let mut registered_themes = THEMES.write().unwrap();
if !registered_themes if !registered_themes
.iter() .iter()
.any(|t| t.handle() == theme.handle()) .any(|t| t.type_id() == theme.type_id())
{ {
registered_themes.push(theme); registered_themes.push(theme);
trace::debug!("Enabling \"{}\" theme", theme.single_name()); trace::debug!("Enabling \"{}\" theme", theme.single_name());

View file

@ -1,19 +1,16 @@
use crate::core::action::Action; use crate::core::action::Action;
use crate::core::theme::ThemeRef; use crate::core::theme::ThemeRef;
use crate::core::AnyBase;
use crate::locale::L10n; use crate::locale::L10n;
use crate::{actions, service, util, ImplementHandle}; use crate::{actions, service};
#[cfg(feature = "database")] #[cfg(feature = "database")]
use crate::{db::MigrationItem, migrations}; use crate::{db::MigrationItem, migrations};
pub type PackageRef = &'static dyn PackageTrait; pub type PackageRef = &'static dyn PackageTrait;
pub trait PackageBase {
fn single_name(&self) -> &'static str;
}
/// Los paquetes deben implementar este *trait*. /// Los paquetes deben implementar este *trait*.
pub trait PackageTrait: ImplementHandle + PackageBase + Send + Sync { pub trait PackageTrait: AnyBase + Send + Sync {
fn name(&self) -> L10n { fn name(&self) -> L10n {
L10n::n(self.single_name()) L10n::n(self.single_name())
} }
@ -41,7 +38,6 @@ pub trait PackageTrait: ImplementHandle + PackageBase + Send + Sync {
fn init(&self) {} fn init(&self) {}
#[cfg(feature = "database")] #[cfg(feature = "database")]
#[allow(unused_variables)]
fn migrations(&self) -> Vec<MigrationItem> { fn migrations(&self) -> Vec<MigrationItem> {
migrations![] migrations![]
} }
@ -49,9 +45,3 @@ pub trait PackageTrait: ImplementHandle + PackageBase + Send + Sync {
#[allow(unused_variables)] #[allow(unused_variables)]
fn configure_service(&self, scfg: &mut service::web::ServiceConfig) {} 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: Cómo usarlo:
match component.handle() { match component.type_id() {
BLOCK_COMPONENT => { t if t == TypeId::of::<Block>() => {
let block = component_as_mut::<Block>(component); if let Some(b) = component_as_mut::<Block>(component) {
block.alter_title("New title"); b.alter_title("New title");
}
}, },
_ => {}, _ => {},
} }
@ -138,10 +139,11 @@ pub trait ThemeTrait: PackageTrait + Send + Sync {
/* /*
Cómo usarlo: Cómo usarlo:
match component.handle() { match component.type_id() {
BLOCK_COMPONENT => { t if t == TypeId::of::<Block>() => {
let block = component_as_mut::<Block>(component); if let Some(b) = component_as_mut::<Block>(component) {
block.alter_title("New title"); b.alter_title("New title");
}
}, },
_ => {}, _ => {},
} }
@ -159,13 +161,9 @@ pub trait ThemeTrait: PackageTrait + Send + Sync {
/* /*
Cómo usarlo: Cómo usarlo:
match component.handle() { match component.type_id() {
BLOCK_COMPONENT => { t if t == TypeId::of::<Block>() => {
let block = component_as_ref::<Block>(component); Some(block_default(block))
match block.template() {
"default" => Some(block_default(block)),
_ => None,
}
}, },
_ => None, _ => None,
} }

View file

@ -1,11 +1,11 @@
use crate::core::component::{AnyComponents, ArcAnyComponent, ArcAnyOp}; use crate::core::component::{AnyComponents, ArcAnyComponent, ArcAnyOp};
use crate::core::theme::ThemeRef; use crate::core::theme::ThemeRef;
use crate::{Handle, LazyStatic, SmartDefault}; use crate::{LazyStatic, SmartDefault, TypeId};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::RwLock; 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())); LazyStatic::new(|| RwLock::new(HashMap::new()));
static COMMON_REGIONS: LazyStatic<RwLock<ComponentsInRegions>> = static COMMON_REGIONS: LazyStatic<RwLock<ComponentsInRegions>> =
@ -31,7 +31,7 @@ impl ComponentsInRegions {
pub fn get_components(&self, theme: ThemeRef, region: &str) -> AnyComponents { pub fn get_components(&self, theme: ThemeRef, region: &str) -> AnyComponents {
let common = COMMON_REGIONS.read().unwrap(); 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)]) AnyComponents::merge(&[common.0.get(region), self.0.get(region), r.0.get(region)])
} else { } else {
AnyComponents::merge(&[common.0.get(region), self.0.get(region)]) 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) => { Region::OfTheme(theme, region) => {
let mut regions = THEME_REGIONS.write().unwrap(); 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); r.add_component_in(region, arc);
} else { } 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 //! ```rust
//! use pagetop::prelude::*; //! use pagetop::prelude::*;
//! //!
//! #[derive(AssignHandle)]
//! struct HelloWorld; //! struct HelloWorld;
//! //!
//! impl PackageTrait for 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. /// Custom derive for automatically implementing the [Default] trait with customized default values.
pub use smart_default::SmartDefault; pub use smart_default::SmartDefault;
pub use pagetop_macros::{fn_with, main, test, AssignHandle, ComponentClasses}; pub use pagetop_macros::{fn_with, main, test, ComponentClasses};
pub(crate) use pagetop_macros::BaseHandle;
// ************************************************************************************************* // *************************************************************************************************
// GLOBAL. // GLOBAL.
@ -96,19 +93,7 @@ pub(crate) use pagetop_macros::BaseHandle;
pub use once_cell::sync::Lazy as LazyStatic; pub use once_cell::sync::Lazy as LazyStatic;
pub use static_files::Resource as StaticResource; pub use static_files::Resource as StaticResource;
pub type Handle = u64; pub use std::any::TypeId;
pub trait ImplementHandle {
fn static_handle() -> Handle
where
Self: Sized;
fn matches_handle(is: Handle) -> bool
where
Self: Sized;
fn handle(&self) -> Handle;
}
pub type Weight = i8; pub type Weight = i8;

View file

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

View file

@ -1,6 +1,6 @@
//! Functions and macro helpers. //! Functions and macro helpers.
use crate::{trace, Handle}; use crate::trace;
use std::io; use std::io;
use std::path::PathBuf; use std::path::PathBuf;
@ -9,41 +9,6 @@ use std::path::PathBuf;
// FUNCTIONS HELPERS. // 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 { pub fn partial_type_name(type_name: &'static str, last: usize) -> &'static str {
if last == 0 { if last == 0 {
return type_name; return type_name;

View file

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