🧑💻 Redefine typed and generic component lists
This commit is contained in:
parent
f208da1b7b
commit
905b4b1cba
12 changed files with 176 additions and 186 deletions
|
|
@ -10,14 +10,14 @@ pub enum FormMethod {
|
|||
#[rustfmt::skip]
|
||||
#[derive(Default)]
|
||||
pub struct Form {
|
||||
id : OptionId,
|
||||
weight : Weight,
|
||||
renderable: Renderable,
|
||||
id : OptionId,
|
||||
classes : OptionClasses,
|
||||
action : OptionString,
|
||||
charset : OptionString,
|
||||
method : FormMethod,
|
||||
stuff : ArcComponents,
|
||||
stuff : AnyComponents,
|
||||
template : String,
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +64,12 @@ impl ComponentTrait for Form {
|
|||
impl Form {
|
||||
// Form BUILDER.
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||
self.id.alter_value(id);
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
||||
self.weight = value;
|
||||
|
|
@ -76,12 +82,6 @@ impl Form {
|
|||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||
self.id.alter_value(id);
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_classes(&mut self, op: ClassesOp, classes: impl Into<String>) -> &mut Self {
|
||||
self.classes.alter_value(op, classes);
|
||||
|
|
@ -106,14 +106,15 @@ impl Form {
|
|||
self
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn with_element(mut self, element: impl ComponentTrait) -> Self {
|
||||
self.stuff.alter(ArcOp::Add(ArcComponent::with(element)));
|
||||
self.stuff.alter_value(ArcAnyOp::Add(ArcAnyComponent::new(element)));
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_elements(&mut self, op: ArcOp) -> &mut Self {
|
||||
self.stuff.alter(op);
|
||||
pub fn alter_elements(&mut self, op: ArcAnyOp) -> &mut Self {
|
||||
self.stuff.alter_value(op);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +142,7 @@ impl Form {
|
|||
&self.method
|
||||
}
|
||||
|
||||
pub fn elements(&self) -> &ArcComponents {
|
||||
pub fn elements(&self) -> &AnyComponents {
|
||||
&self.stuff
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use crate::prelude::*;
|
|||
|
||||
use super::Submenu;
|
||||
|
||||
type Content = TypedComponent<Html>;
|
||||
type SubmenuItems = TypedComponent<Submenu>;
|
||||
type Content = ArcTypedComponent<Html>;
|
||||
type SubmenuItems = ArcTypedComponent<Submenu>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub enum ElementType {
|
||||
|
|
@ -54,14 +54,14 @@ impl ComponentTrait for Element {
|
|||
impl Element {
|
||||
pub fn html(content: Html) -> Self {
|
||||
Element {
|
||||
element_type: ElementType::Html(Content::with(content)),
|
||||
element_type: ElementType::Html(Content::new(content)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn submenu(submenu: Submenu) -> Self {
|
||||
Element {
|
||||
element_type: ElementType::Submenu(SubmenuItems::with(submenu)),
|
||||
element_type: ElementType::Submenu(SubmenuItems::new(submenu)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,13 @@ use crate::prelude::*;
|
|||
|
||||
use super::Element;
|
||||
|
||||
type Elements = TypedComponents<Element>;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Default)]
|
||||
pub struct Group {
|
||||
id : OptionId,
|
||||
weight : Weight,
|
||||
renderable: Renderable,
|
||||
id : OptionId,
|
||||
elements : Elements,
|
||||
elements : TypedComponents<Element>,
|
||||
}
|
||||
|
||||
impl_handle!(COMPONENT_BASE_MENU_GROUP for Group);
|
||||
|
|
@ -44,6 +42,12 @@ impl ComponentTrait for Group {
|
|||
impl Group {
|
||||
// Group BUILDER.
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||
self.id.alter_value(id);
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
||||
self.weight = value;
|
||||
|
|
@ -56,27 +60,21 @@ impl Group {
|
|||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||
self.id.alter_value(id);
|
||||
self
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn add_element(mut self, element: Element) -> Self {
|
||||
self.elements
|
||||
.alter(TypedOp::Add(TypedComponent::with(element)));
|
||||
self.elements.alter_value(ArcTypedOp::Add(ArcTypedComponent::new(element)));
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_elements(&mut self, op: TypedOp<Element>) -> &mut Self {
|
||||
self.elements.alter(op);
|
||||
pub fn alter_elements(&mut self, op: ArcTypedOp<Element>) -> &mut Self {
|
||||
self.elements.alter_value(op);
|
||||
self
|
||||
}
|
||||
|
||||
// Group GETTERS.
|
||||
|
||||
pub fn elements(&self) -> &Elements {
|
||||
pub fn elements(&self) -> &TypedComponents<Element> {
|
||||
&self.elements
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ use crate::prelude::*;
|
|||
use super::{Megamenu, Submenu};
|
||||
|
||||
type Label = L10n;
|
||||
type Content = TypedComponent<Html>;
|
||||
type SubmenuItems = TypedComponent<Submenu>;
|
||||
type MegamenuGroups = TypedComponent<Megamenu>;
|
||||
type Content = ArcTypedComponent<Html>;
|
||||
type SubmenuItems = ArcTypedComponent<Submenu>;
|
||||
type MegamenuGroups = ArcTypedComponent<Megamenu>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub enum ItemType {
|
||||
|
|
@ -123,21 +123,21 @@ impl Item {
|
|||
|
||||
pub fn html(content: Html) -> Self {
|
||||
Item {
|
||||
item_type: ItemType::Html(Content::with(content)),
|
||||
item_type: ItemType::Html(Content::new(content)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn submenu(label: L10n, submenu: Submenu) -> Self {
|
||||
Item {
|
||||
item_type: ItemType::Submenu(label, SubmenuItems::with(submenu)),
|
||||
item_type: ItemType::Submenu(label, SubmenuItems::new(submenu)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn megamenu(label: L10n, megamenu: Megamenu) -> Self {
|
||||
Item {
|
||||
item_type: ItemType::Megamenu(label, MegamenuGroups::with(megamenu)),
|
||||
item_type: ItemType::Megamenu(label, MegamenuGroups::new(megamenu)),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,13 @@ use crate::prelude::*;
|
|||
|
||||
use super::Group;
|
||||
|
||||
type Groups = TypedComponents<Group>;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Default)]
|
||||
pub struct Megamenu {
|
||||
id : OptionId,
|
||||
weight : Weight,
|
||||
renderable: Renderable,
|
||||
id : OptionId,
|
||||
groups : Groups,
|
||||
groups : TypedComponents<Group>,
|
||||
}
|
||||
|
||||
impl_handle!(COMPONENT_BASE_MENU_MEGAMENU for Megamenu);
|
||||
|
|
@ -44,6 +42,12 @@ impl ComponentTrait for Megamenu {
|
|||
impl Megamenu {
|
||||
// Megamenu BUILDER.
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||
self.id.alter_value(id);
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
||||
self.weight = value;
|
||||
|
|
@ -56,26 +60,21 @@ impl Megamenu {
|
|||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||
self.id.alter_value(id);
|
||||
self
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn add_group(mut self, group: Group) -> Self {
|
||||
self.groups.alter(TypedOp::Add(TypedComponent::with(group)));
|
||||
self.groups.alter_value(ArcTypedOp::Add(ArcTypedComponent::new(group)));
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_groups(&mut self, op: TypedOp<Group>) -> &mut Self {
|
||||
self.groups.alter(op);
|
||||
pub fn alter_groups(&mut self, op: ArcTypedOp<Group>) -> &mut Self {
|
||||
self.groups.alter_value(op);
|
||||
self
|
||||
}
|
||||
|
||||
// Megamenu GETTERS.
|
||||
|
||||
pub fn groups(&self) -> &Groups {
|
||||
pub fn groups(&self) -> &TypedComponents<Group> {
|
||||
&self.groups
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ use super::Item;
|
|||
#[rustfmt::skip]
|
||||
#[derive(Default)]
|
||||
pub struct Menu {
|
||||
id : OptionId,
|
||||
weight : Weight,
|
||||
renderable: Renderable,
|
||||
id : OptionId,
|
||||
items : TypedComponents<Item>,
|
||||
}
|
||||
|
||||
|
|
@ -70,6 +70,12 @@ impl ComponentTrait for Menu {
|
|||
impl Menu {
|
||||
// Menu BUILDER.
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||
self.id.alter_value(id);
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
||||
self.weight = value;
|
||||
|
|
@ -82,20 +88,15 @@ impl Menu {
|
|||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||
self.id.alter_value(id);
|
||||
self
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn add_item(mut self, item: Item) -> Self {
|
||||
self.items.alter(TypedOp::Add(TypedComponent::with(item)));
|
||||
self.items.alter_value(ArcTypedOp::Add(ArcTypedComponent::new(item)));
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_items(&mut self, op: TypedOp<Item>) -> &mut Self {
|
||||
self.items.alter(op);
|
||||
pub fn alter_items(&mut self, op: ArcTypedOp<Item>) -> &mut Self {
|
||||
self.items.alter_value(op);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,16 +2,14 @@ use crate::prelude::*;
|
|||
|
||||
use super::Item;
|
||||
|
||||
type Items = TypedComponents<Item>;
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Default)]
|
||||
pub struct Submenu {
|
||||
id : OptionId,
|
||||
weight : Weight,
|
||||
renderable: Renderable,
|
||||
id : OptionId,
|
||||
title : OptionTranslated,
|
||||
items : Items,
|
||||
items : TypedComponents<Item>,
|
||||
}
|
||||
|
||||
impl_handle!(COMPONENT_BASE_MENU_SUBMENU for Submenu);
|
||||
|
|
@ -50,6 +48,12 @@ impl ComponentTrait for Submenu {
|
|||
impl Submenu {
|
||||
// Submenu BUILDER.
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||
self.id.alter_value(id);
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_weight(&mut self, value: Weight) -> &mut Self {
|
||||
self.weight = value;
|
||||
|
|
@ -62,26 +66,21 @@ impl Submenu {
|
|||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||
self.id.alter_value(id);
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_title(&mut self, title: L10n) -> &mut Self {
|
||||
self.title.alter_value(title);
|
||||
self
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn add_item(mut self, item: Item) -> Self {
|
||||
self.items.alter(TypedOp::Add(TypedComponent::with(item)));
|
||||
self.items.alter_value(ArcTypedOp::Add(ArcTypedComponent::new(item)));
|
||||
self
|
||||
}
|
||||
|
||||
#[fn_builder]
|
||||
pub fn alter_items(&mut self, op: TypedOp<Item>) -> &mut Self {
|
||||
self.items.alter(op);
|
||||
pub fn alter_items(&mut self, op: ArcTypedOp<Item>) -> &mut Self {
|
||||
self.items.alter_value(op);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +90,7 @@ impl Submenu {
|
|||
&self.title
|
||||
}
|
||||
|
||||
pub fn items(&self) -> &Items {
|
||||
pub fn items(&self) -> &TypedComponents<Item> {
|
||||
&self.items
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,10 @@ pub use renderable::{FnIsRenderable, Renderable};
|
|||
mod definition;
|
||||
pub use definition::{component_as_mut, component_as_ref, ComponentBase, ComponentTrait};
|
||||
|
||||
mod arc;
|
||||
pub use arc::{ArcComponent, ArcComponents, ArcOp};
|
||||
mod arc_any;
|
||||
pub use arc_any::AnyComponents;
|
||||
pub use arc_any::{ArcAnyComponent, ArcAnyOp};
|
||||
|
||||
mod typed;
|
||||
pub use typed::{TypedComponent, TypedComponents, TypedOp};
|
||||
mod arc_typed;
|
||||
pub use arc_typed::TypedComponents;
|
||||
pub use arc_typed::{ArcTypedComponent, ArcTypedOp};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::core::component::{ComponentTrait, Context};
|
||||
use crate::html::{html, Markup};
|
||||
use crate::{impl_handle, Handle, Weight};
|
||||
use crate::{fn_builder, impl_handle, Handle, Weight};
|
||||
|
||||
use std::sync::{Arc, RwLock, RwLockReadGuard};
|
||||
|
||||
|
|
@ -16,30 +16,26 @@ impl ComponentTrait for ComponentNull {
|
|||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ArcComponent(Arc<RwLock<dyn ComponentTrait>>);
|
||||
pub struct ArcAnyComponent(Arc<RwLock<dyn ComponentTrait>>);
|
||||
|
||||
impl Default for ArcComponent {
|
||||
impl Default for ArcAnyComponent {
|
||||
fn default() -> Self {
|
||||
ArcComponent(Arc::new(RwLock::new(ComponentNull)))
|
||||
ArcAnyComponent(Arc::new(RwLock::new(ComponentNull)))
|
||||
}
|
||||
}
|
||||
|
||||
impl ArcComponent {
|
||||
pub fn new() -> Self {
|
||||
ArcComponent::default()
|
||||
impl ArcAnyComponent {
|
||||
pub fn new(component: impl ComponentTrait) -> Self {
|
||||
ArcAnyComponent(Arc::new(RwLock::new(component)))
|
||||
}
|
||||
|
||||
pub fn with(component: impl ComponentTrait) -> Self {
|
||||
ArcComponent(Arc::new(RwLock::new(component)))
|
||||
}
|
||||
|
||||
// ArcComponent BUILDER.
|
||||
// ArcAnyComponent BUILDER.
|
||||
|
||||
pub fn set(&mut self, component: impl ComponentTrait) {
|
||||
self.0 = Arc::new(RwLock::new(component));
|
||||
}
|
||||
|
||||
// ArcComponent GETTERS.
|
||||
// ArcAnyComponent GETTERS.
|
||||
|
||||
pub fn get(&self) -> RwLockReadGuard<'_, dyn ComponentTrait> {
|
||||
self.0.read().unwrap()
|
||||
|
|
@ -57,69 +53,66 @@ impl ArcComponent {
|
|||
self.0.read().unwrap().weight()
|
||||
}
|
||||
|
||||
// ArcComponent RENDER.
|
||||
// ArcAnyComponent RENDER.
|
||||
|
||||
pub fn render(&self, cx: &mut Context) -> Markup {
|
||||
self.0.write().unwrap().render(cx)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ArcOp {
|
||||
Add(ArcComponent),
|
||||
AddAfterId(&'static str, ArcComponent),
|
||||
AddBeforeId(&'static str, ArcComponent),
|
||||
AddFirst(ArcComponent),
|
||||
// *************************************************************************************************
|
||||
|
||||
pub enum ArcAnyOp {
|
||||
Add(ArcAnyComponent),
|
||||
AddAfterId(&'static str, ArcAnyComponent),
|
||||
AddBeforeId(&'static str, ArcAnyComponent),
|
||||
AddFirst(ArcAnyComponent),
|
||||
RemoveById(&'static str),
|
||||
ReplaceById(&'static str, ArcComponent),
|
||||
ReplaceById(&'static str, ArcAnyComponent),
|
||||
Reset,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ArcComponents(Vec<ArcComponent>);
|
||||
pub struct AnyComponents(Vec<ArcAnyComponent>);
|
||||
|
||||
impl ArcComponents {
|
||||
pub fn new() -> Self {
|
||||
ArcComponents::default()
|
||||
impl AnyComponents {
|
||||
pub fn new(arc: ArcAnyComponent) -> Self {
|
||||
AnyComponents::default().with_value(ArcAnyOp::Add(arc))
|
||||
}
|
||||
|
||||
pub fn with(arc: ArcComponent) -> Self {
|
||||
let mut components = ArcComponents::new();
|
||||
components.alter(ArcOp::Add(arc));
|
||||
components
|
||||
}
|
||||
|
||||
pub(crate) fn merge(mixes: &[Option<&ArcComponents>]) -> Self {
|
||||
let mut components = ArcComponents::default();
|
||||
pub(crate) fn merge(mixes: &[Option<&AnyComponents>]) -> Self {
|
||||
let mut opt = AnyComponents::default();
|
||||
for m in mixes.iter().flatten() {
|
||||
components.0.append(&mut m.0.clone());
|
||||
opt.0.append(&mut m.0.clone());
|
||||
}
|
||||
components
|
||||
opt
|
||||
}
|
||||
|
||||
// ArcComponents BUILDER.
|
||||
// AnyComponents BUILDER.
|
||||
|
||||
pub fn alter(&mut self, op: ArcOp) -> &mut Self {
|
||||
#[fn_builder]
|
||||
pub fn alter_value(&mut self, op: ArcAnyOp) -> &mut Self {
|
||||
match op {
|
||||
ArcOp::Add(arc) => self.0.push(arc),
|
||||
ArcOp::AddAfterId(id, arc) => {
|
||||
ArcAnyOp::Add(arc) => self.0.push(arc),
|
||||
ArcAnyOp::AddAfterId(id, arc) => {
|
||||
match self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
||||
Some(index) => self.0.insert(index + 1, arc),
|
||||
_ => self.0.push(arc),
|
||||
}
|
||||
}
|
||||
ArcOp::AddBeforeId(id, arc) => {
|
||||
ArcAnyOp::AddBeforeId(id, arc) => {
|
||||
match self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
||||
Some(index) => self.0.insert(index, arc),
|
||||
_ => self.0.insert(0, arc),
|
||||
}
|
||||
}
|
||||
ArcOp::AddFirst(arc) => self.0.insert(0, arc),
|
||||
ArcOp::RemoveById(id) => {
|
||||
ArcAnyOp::AddFirst(arc) => self.0.insert(0, arc),
|
||||
ArcAnyOp::RemoveById(id) => {
|
||||
if let Some(index) = self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
||||
self.0.remove(index);
|
||||
}
|
||||
}
|
||||
ArcOp::ReplaceById(id, arc) => {
|
||||
ArcAnyOp::ReplaceById(id, arc) => {
|
||||
for c in self.0.iter_mut() {
|
||||
if c.id().as_deref() == Some(id) {
|
||||
*c = arc;
|
||||
|
|
@ -127,26 +120,30 @@ impl ArcComponents {
|
|||
}
|
||||
}
|
||||
}
|
||||
ArcOp::Reset => self.0.clear(),
|
||||
ArcAnyOp::Reset => self.0.clear(),
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
// ArcComponents GETTERS.
|
||||
// AnyComponents GETTERS.
|
||||
|
||||
pub fn get_by_id(&self, id: &'static str) -> Option<&ArcComponent> {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn get_by_id(&self, id: &'static str) -> Option<&ArcAnyComponent> {
|
||||
self.0.iter().find(|&c| c.id().as_deref() == Some(id))
|
||||
}
|
||||
|
||||
pub fn iter_by_id(&self, id: &'static str) -> impl Iterator<Item = &ArcComponent> {
|
||||
pub fn iter_by_id(&self, id: &'static str) -> impl Iterator<Item = &ArcAnyComponent> {
|
||||
self.0.iter().filter(|&c| c.id().as_deref() == Some(id))
|
||||
}
|
||||
|
||||
pub fn iter_by_handle(&self, handle: Handle) -> impl Iterator<Item = &ArcComponent> {
|
||||
pub fn iter_by_handle(&self, handle: Handle) -> impl Iterator<Item = &ArcAnyComponent> {
|
||||
self.0.iter().filter(move |&c| c.handle() == handle)
|
||||
}
|
||||
|
||||
// ArcComponents RENDER.
|
||||
// AnyComponents RENDER.
|
||||
|
||||
pub fn render(&self, cx: &mut Context) -> Markup {
|
||||
let mut components = self.0.clone();
|
||||
|
|
@ -1,34 +1,30 @@
|
|||
use crate::core::component::{ComponentTrait, Context};
|
||||
use crate::html::{html, Markup};
|
||||
use crate::{Handle, Weight};
|
||||
use crate::{fn_builder, Handle, Weight};
|
||||
|
||||
use std::sync::{Arc, RwLock, RwLockReadGuard};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct TypedComponent<T: ComponentTrait + Default>(Arc<RwLock<T>>);
|
||||
pub struct ArcTypedComponent<T: ComponentTrait>(Arc<RwLock<T>>);
|
||||
|
||||
impl<T: ComponentTrait + Default> Clone for TypedComponent<T> {
|
||||
impl<T: ComponentTrait> Clone for ArcTypedComponent<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ComponentTrait + Default> TypedComponent<T> {
|
||||
pub fn new() -> Self {
|
||||
TypedComponent::<T>::default()
|
||||
impl<T: ComponentTrait> ArcTypedComponent<T> {
|
||||
pub fn new(component: T) -> Self {
|
||||
ArcTypedComponent(Arc::new(RwLock::new(component)))
|
||||
}
|
||||
|
||||
pub fn with(component: T) -> Self {
|
||||
TypedComponent(Arc::new(RwLock::new(component)))
|
||||
}
|
||||
|
||||
// TypedComponent BUILDER.
|
||||
// ArcTypedComponent BUILDER.
|
||||
|
||||
pub fn set(&mut self, component: T) {
|
||||
self.0 = Arc::new(RwLock::new(component));
|
||||
}
|
||||
|
||||
// TypedComponent GETTERS.
|
||||
// ArcTypedComponent GETTERS.
|
||||
|
||||
pub fn get(&self) -> RwLockReadGuard<'_, T> {
|
||||
self.0.read().unwrap()
|
||||
|
|
@ -46,61 +42,58 @@ impl<T: ComponentTrait + Default> TypedComponent<T> {
|
|||
self.0.read().unwrap().weight()
|
||||
}
|
||||
|
||||
// TypedComponent RENDER.
|
||||
// ArcTypedComponent RENDER.
|
||||
|
||||
pub fn render(&self, cx: &mut Context) -> Markup {
|
||||
self.0.write().unwrap().render(cx)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TypedOp<T: ComponentTrait + Default> {
|
||||
Add(TypedComponent<T>),
|
||||
AddAfterId(&'static str, TypedComponent<T>),
|
||||
AddBeforeId(&'static str, TypedComponent<T>),
|
||||
AddFirst(TypedComponent<T>),
|
||||
// *************************************************************************************************
|
||||
|
||||
pub enum ArcTypedOp<T: ComponentTrait + Default> {
|
||||
Add(ArcTypedComponent<T>),
|
||||
AddAfterId(&'static str, ArcTypedComponent<T>),
|
||||
AddBeforeId(&'static str, ArcTypedComponent<T>),
|
||||
AddFirst(ArcTypedComponent<T>),
|
||||
RemoveById(&'static str),
|
||||
ReplaceById(&'static str, TypedComponent<T>),
|
||||
ReplaceById(&'static str, ArcTypedComponent<T>),
|
||||
Reset,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct TypedComponents<T: ComponentTrait + Default>(Vec<TypedComponent<T>>);
|
||||
pub struct TypedComponents<T: ComponentTrait + Default>(Vec<ArcTypedComponent<T>>);
|
||||
|
||||
impl<T: ComponentTrait + Default> TypedComponents<T> {
|
||||
pub fn new() -> Self {
|
||||
TypedComponents::<T>::default()
|
||||
}
|
||||
|
||||
pub fn with(one: TypedComponent<T>) -> Self {
|
||||
let mut components = TypedComponents::new();
|
||||
components.alter(TypedOp::Add(one));
|
||||
components
|
||||
pub fn new(arc: ArcTypedComponent<T>) -> Self {
|
||||
TypedComponents::default().with_value(ArcTypedOp::Add(arc))
|
||||
}
|
||||
|
||||
// TypedComponents BUILDER.
|
||||
|
||||
pub fn alter(&mut self, op: TypedOp<T>) -> &mut Self {
|
||||
#[fn_builder]
|
||||
pub fn alter_value(&mut self, op: ArcTypedOp<T>) -> &mut Self {
|
||||
match op {
|
||||
TypedOp::Add(one) => self.0.push(one),
|
||||
TypedOp::AddAfterId(id, one) => {
|
||||
ArcTypedOp::Add(one) => self.0.push(one),
|
||||
ArcTypedOp::AddAfterId(id, one) => {
|
||||
match self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
||||
Some(index) => self.0.insert(index + 1, one),
|
||||
_ => self.0.push(one),
|
||||
}
|
||||
}
|
||||
TypedOp::AddBeforeId(id, one) => {
|
||||
ArcTypedOp::AddBeforeId(id, one) => {
|
||||
match self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
||||
Some(index) => self.0.insert(index, one),
|
||||
_ => self.0.insert(0, one),
|
||||
}
|
||||
}
|
||||
TypedOp::AddFirst(one) => self.0.insert(0, one),
|
||||
TypedOp::RemoveById(id) => {
|
||||
ArcTypedOp::AddFirst(one) => self.0.insert(0, one),
|
||||
ArcTypedOp::RemoveById(id) => {
|
||||
if let Some(index) = self.0.iter().position(|c| c.id().as_deref() == Some(id)) {
|
||||
self.0.remove(index);
|
||||
}
|
||||
}
|
||||
TypedOp::ReplaceById(id, one) => {
|
||||
ArcTypedOp::ReplaceById(id, one) => {
|
||||
for c in self.0.iter_mut() {
|
||||
if c.id().as_deref() == Some(id) {
|
||||
*c = one;
|
||||
|
|
@ -108,22 +101,26 @@ impl<T: ComponentTrait + Default> TypedComponents<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
TypedOp::Reset => self.0.clear(),
|
||||
ArcTypedOp::Reset => self.0.clear(),
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
// TypedComponents GETTERS.
|
||||
|
||||
pub fn get_by_id(&self, id: &'static str) -> Option<&TypedComponent<T>> {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn get_by_id(&self, id: &'static str) -> Option<&ArcTypedComponent<T>> {
|
||||
self.0.iter().find(|&c| c.id().as_deref() == Some(id))
|
||||
}
|
||||
|
||||
pub fn iter_by_id(&self, id: &'static str) -> impl Iterator<Item = &TypedComponent<T>> {
|
||||
pub fn iter_by_id(&self, id: &'static str) -> impl Iterator<Item = &ArcTypedComponent<T>> {
|
||||
self.0.iter().filter(|&c| c.id().as_deref() == Some(id))
|
||||
}
|
||||
|
||||
pub fn iter_by_handle(&self, handle: Handle) -> impl Iterator<Item = &TypedComponent<T>> {
|
||||
pub fn iter_by_handle(&self, handle: Handle) -> impl Iterator<Item = &ArcTypedComponent<T>> {
|
||||
self.0.iter().filter(move |&c| c.handle() == handle)
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::core::component::{ArcComponent, ArcComponents, ArcOp};
|
||||
use crate::core::component::{AnyComponents, ArcAnyComponent, ArcAnyOp};
|
||||
use crate::core::theme::ThemeRef;
|
||||
use crate::{Handle, LazyStatic};
|
||||
|
||||
|
|
@ -9,36 +9,32 @@ static THEME_REGIONS: LazyStatic<RwLock<HashMap<Handle, ComponentsRegions>>> =
|
|||
LazyStatic::new(|| RwLock::new(HashMap::new()));
|
||||
|
||||
static COMMON_REGIONS: LazyStatic<RwLock<ComponentsRegions>> =
|
||||
LazyStatic::new(|| RwLock::new(ComponentsRegions::new()));
|
||||
LazyStatic::new(|| RwLock::new(ComponentsRegions::default()));
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ComponentsRegions(HashMap<&'static str, ArcComponents>);
|
||||
pub struct ComponentsRegions(HashMap<&'static str, AnyComponents>);
|
||||
|
||||
impl ComponentsRegions {
|
||||
pub fn new() -> Self {
|
||||
ComponentsRegions::default()
|
||||
}
|
||||
|
||||
pub fn with(region: &'static str, arc: ArcComponent) -> Self {
|
||||
let mut regions = ComponentsRegions::new();
|
||||
pub fn new(region: &'static str, arc: ArcAnyComponent) -> Self {
|
||||
let mut regions = ComponentsRegions::default();
|
||||
regions.add_in(region, arc);
|
||||
regions
|
||||
}
|
||||
|
||||
pub fn add_in(&mut self, region: &'static str, arc: ArcComponent) {
|
||||
pub fn add_in(&mut self, region: &'static str, arc: ArcAnyComponent) {
|
||||
if let Some(region) = self.0.get_mut(region) {
|
||||
region.alter(ArcOp::Add(arc));
|
||||
region.alter_value(ArcAnyOp::Add(arc));
|
||||
} else {
|
||||
self.0.insert(region, ArcComponents::with(arc));
|
||||
self.0.insert(region, AnyComponents::new(arc));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_components(&self, theme: ThemeRef, region: &str) -> ArcComponents {
|
||||
pub fn get_components(&self, theme: ThemeRef, region: &str) -> AnyComponents {
|
||||
let common = COMMON_REGIONS.read().unwrap();
|
||||
if let Some(hm) = THEME_REGIONS.read().unwrap().get(&theme.handle()) {
|
||||
ArcComponents::merge(&[common.0.get(region), self.0.get(region), hm.0.get(region)])
|
||||
AnyComponents::merge(&[common.0.get(region), self.0.get(region), hm.0.get(region)])
|
||||
} else {
|
||||
ArcComponents::merge(&[common.0.get(region), self.0.get(region)])
|
||||
AnyComponents::merge(&[common.0.get(region), self.0.get(region)])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -48,7 +44,7 @@ pub enum Region {
|
|||
OfTheme(ThemeRef, &'static str),
|
||||
}
|
||||
|
||||
pub fn add_component_in(region: Region, arc: ArcComponent) {
|
||||
pub fn add_component_in(region: Region, arc: ArcAnyComponent) {
|
||||
match region {
|
||||
Region::Named(name) => {
|
||||
COMMON_REGIONS.write().unwrap().add_in(name, arc);
|
||||
|
|
@ -58,7 +54,7 @@ pub fn add_component_in(region: Region, arc: ArcComponent) {
|
|||
if let Some(hm) = regions.get_mut(&theme.handle()) {
|
||||
hm.add_in(region, arc);
|
||||
} else {
|
||||
regions.insert(theme.handle(), ComponentsRegions::with(region, arc));
|
||||
regions.insert(theme.handle(), ComponentsRegions::new(region, arc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::base::action;
|
||||
use crate::core::component::{ArcComponent, ArcComponents as RegionComponents, ComponentTrait};
|
||||
use crate::core::component::{AnyComponents, ArcAnyComponent, ComponentTrait};
|
||||
use crate::core::component::{Context, ContextOp};
|
||||
use crate::core::theme::ComponentsRegions;
|
||||
use crate::html::{html, Markup, DOCTYPE};
|
||||
|
|
@ -95,7 +95,7 @@ impl Page {
|
|||
|
||||
#[fn_builder]
|
||||
pub fn alter_in(&mut self, region: &'static str, component: impl ComponentTrait) -> &mut Self {
|
||||
self.regions.add_in(region, ArcComponent::with(component));
|
||||
self.regions.add_in(region, ArcAnyComponent::new(component));
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +139,7 @@ impl Page {
|
|||
&self.skip_to
|
||||
}
|
||||
|
||||
pub fn components_in(&self, region: &str) -> RegionComponents {
|
||||
pub fn components_in(&self, region: &str) -> AnyComponents {
|
||||
self.regions.get_components(self.context.theme(), region)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue