🔥 Elimina definitivamente TypedOpt
por Typed
This commit is contained in:
parent
476ea7de7f
commit
f5290b477f
4 changed files with 56 additions and 90 deletions
|
@ -7,6 +7,3 @@ mod children;
|
||||||
pub use children::Children;
|
pub use children::Children;
|
||||||
pub use children::{Child, ChildOp};
|
pub use children::{Child, ChildOp};
|
||||||
pub use children::{Typed, TypedOp};
|
pub use children::{Typed, TypedOp};
|
||||||
|
|
||||||
mod optional;
|
|
||||||
pub use optional::TypedOpt;
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::core::component::Component;
|
use crate::core::component::Component;
|
||||||
use crate::html::{html, Context, Markup};
|
use crate::html::{html, Context, Markup};
|
||||||
use crate::{builder_fn, UniqueId};
|
use crate::{builder_fn, AutoDefault, UniqueId};
|
||||||
|
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
|
@ -11,76 +11,105 @@ use std::vec::IntoIter;
|
||||||
///
|
///
|
||||||
/// Esta estructura permite manipular y renderizar un componente que implemente [`Component`], y
|
/// Esta estructura permite manipular y renderizar un componente que implemente [`Component`], y
|
||||||
/// habilita acceso concurrente mediante [`Arc<RwLock<_>>`].
|
/// habilita acceso concurrente mediante [`Arc<RwLock<_>>`].
|
||||||
#[derive(Clone)]
|
#[derive(AutoDefault, Clone)]
|
||||||
pub struct Child(Arc<RwLock<dyn Component>>);
|
pub struct Child(Option<Arc<RwLock<dyn Component>>>);
|
||||||
|
|
||||||
impl Child {
|
impl Child {
|
||||||
/// Crea un nuevo `Child` a partir de un componente.
|
/// Crea un nuevo `Child` a partir de un componente.
|
||||||
pub fn with(component: impl Component) -> Self {
|
pub fn with(component: impl Component) -> Self {
|
||||||
Child(Arc::new(RwLock::new(component)))
|
Child(Some(Arc::new(RwLock::new(component))))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Child BUILDER *******************************************************************************
|
||||||
|
|
||||||
|
/// Establece un componente nuevo, o lo vacía.
|
||||||
|
///
|
||||||
|
/// Si se proporciona `Some(component)`, se encapsula como [`Child`]; y si es `None`, se limpia.
|
||||||
|
#[builder_fn]
|
||||||
|
pub fn with_component<C: Component>(mut self, component: Option<C>) -> Self {
|
||||||
|
if let Some(c) = component {
|
||||||
|
self.0 = Some(Arc::new(RwLock::new(c)));
|
||||||
|
} else {
|
||||||
|
self.0 = None;
|
||||||
|
}
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
// Child GETTERS *******************************************************************************
|
// Child GETTERS *******************************************************************************
|
||||||
|
|
||||||
/// Devuelve el identificador del componente, si está definido.
|
/// Devuelve el identificador del componente, si existe y está definido.
|
||||||
|
#[inline]
|
||||||
pub fn id(&self) -> Option<String> {
|
pub fn id(&self) -> Option<String> {
|
||||||
self.0.read().id()
|
self.0.as_ref().and_then(|c| c.read().id())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Child RENDER ********************************************************************************
|
// Child RENDER ********************************************************************************
|
||||||
|
|
||||||
/// Renderiza el componente con el contexto proporcionado.
|
/// Renderiza el componente con el contexto proporcionado.
|
||||||
pub fn render(&self, cx: &mut Context) -> Markup {
|
pub fn render(&self, cx: &mut Context) -> Markup {
|
||||||
self.0.write().render(cx)
|
self.0.as_ref().map_or(html! {}, |c| c.write().render(cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Child HELPERS *******************************************************************************
|
// Child HELPERS *******************************************************************************
|
||||||
|
|
||||||
// Devuelve el [`UniqueId`] del tipo del componente.
|
// Devuelve el [`UniqueId`] del tipo del componente, si existe.
|
||||||
fn type_id(&self) -> UniqueId {
|
#[inline]
|
||||||
self.0.read().type_id()
|
fn type_id(&self) -> Option<UniqueId> {
|
||||||
|
self.0.as_ref().map(|c| c.read().type_id())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
|
|
||||||
/// Variante tipada de [`Child`] para evitar conversiones durante el uso.
|
/// Variante tipada de [`Child`] para evitar conversiones de tipo durante el uso.
|
||||||
///
|
///
|
||||||
/// Esta estructura permite manipular y renderizar un componente concreto que implemente
|
/// Esta estructura permite manipular y renderizar un componente concreto que implemente
|
||||||
/// [`Component`], y habilita acceso concurrente mediante [`Arc<RwLock<_>>`].
|
/// [`Component`], y habilita acceso concurrente mediante [`Arc<RwLock<_>>`].
|
||||||
pub struct Typed<C: Component>(Arc<RwLock<C>>);
|
#[derive(AutoDefault, Clone)]
|
||||||
|
pub struct Typed<C: Component>(Option<Arc<RwLock<C>>>);
|
||||||
impl<C: Component> Clone for Typed<C> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self(self.0.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: Component> Typed<C> {
|
impl<C: Component> Typed<C> {
|
||||||
/// Crea un nuevo `Typed` a partir de un componente.
|
/// Crea un nuevo `Typed` a partir de un componente.
|
||||||
pub fn with(component: C) -> Self {
|
pub fn with(component: C) -> Self {
|
||||||
Typed(Arc::new(RwLock::new(component)))
|
Typed(Some(Arc::new(RwLock::new(component))))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Typed BUILDER *******************************************************************************
|
||||||
|
|
||||||
|
/// Establece un componente nuevo, o lo vacía.
|
||||||
|
///
|
||||||
|
/// Si se proporciona `Some(component)`, se encapsula como [`Typed`]; y si es `None`, se limpia.
|
||||||
|
#[builder_fn]
|
||||||
|
pub fn with_component(mut self, component: Option<C>) -> Self {
|
||||||
|
self.0 = component.map(|c| Arc::new(RwLock::new(c)));
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
// Typed GETTERS *******************************************************************************
|
// Typed GETTERS *******************************************************************************
|
||||||
|
|
||||||
/// Devuelve el identificador del componente, si está definido.
|
/// Devuelve el identificador del componente, si existe y está definido.
|
||||||
|
#[inline]
|
||||||
pub fn id(&self) -> Option<String> {
|
pub fn id(&self) -> Option<String> {
|
||||||
self.0.read().id()
|
self.0.as_ref().and_then(|c| c.read().id())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Typed RENDER ********************************************************************************
|
// Typed RENDER ********************************************************************************
|
||||||
|
|
||||||
/// Renderiza el componente con el contexto proporcionado.
|
/// Renderiza el componente con el contexto proporcionado.
|
||||||
pub fn render(&self, cx: &mut Context) -> Markup {
|
pub fn render(&self, cx: &mut Context) -> Markup {
|
||||||
self.0.write().render(cx)
|
self.0.as_ref().map_or(html! {}, |c| c.write().render(cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Typed HELPERS *******************************************************************************
|
// Typed HELPERS *******************************************************************************
|
||||||
|
|
||||||
// Convierte el componente tipado en un [`Child`].
|
// Convierte el componente tipado en un [`Child`].
|
||||||
|
#[inline]
|
||||||
fn into_child(self) -> Child {
|
fn into_child(self) -> Child {
|
||||||
Child(self.0.clone())
|
if let Some(c) = &self.0 {
|
||||||
|
Child(Some(c.clone()))
|
||||||
|
} else {
|
||||||
|
Child(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +230,7 @@ impl Children {
|
||||||
/// Devuelve un iterador sobre los componentes hijo con el identificador de tipo ([`UniqueId`])
|
/// Devuelve un iterador sobre los componentes hijo con el identificador de tipo ([`UniqueId`])
|
||||||
/// indicado.
|
/// indicado.
|
||||||
pub fn iter_by_type_id(&self, type_id: UniqueId) -> impl Iterator<Item = &Child> {
|
pub fn iter_by_type_id(&self, type_id: UniqueId) -> impl Iterator<Item = &Child> {
|
||||||
self.0.iter().filter(move |&c| c.type_id() == type_id)
|
self.0.iter().filter(move |&c| c.type_id() == Some(type_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Children RENDER *****************************************************************************
|
// Children RENDER *****************************************************************************
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
use crate::core::component::{Component, Typed};
|
|
||||||
use crate::html::{html, Context, Markup};
|
|
||||||
use crate::{builder_fn, AutoDefault};
|
|
||||||
|
|
||||||
/// Contenedor **opcional** para un componente [`Typed`].
|
|
||||||
///
|
|
||||||
/// Un `TypedOpt` actúa como un contenedor para incluir o no un subcomponente tipado. Internamente
|
|
||||||
/// encapsula `Option<Typed<C>>`, pero ofrece una API más sencilla para construir estructuras
|
|
||||||
/// jerárquicas o contenidas de componentes.
|
|
||||||
///
|
|
||||||
/// # Ejemplo
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// use pagetop::prelude::*;
|
|
||||||
///
|
|
||||||
/// let icon = Icon::default();
|
|
||||||
/// let icon = TypedOpt::new(icon);
|
|
||||||
/// assert!(icon.get().is_some());
|
|
||||||
/// ```
|
|
||||||
#[derive(AutoDefault)]
|
|
||||||
pub struct TypedOpt<C: Component>(Option<Typed<C>>);
|
|
||||||
|
|
||||||
impl<C: Component> TypedOpt<C> {
|
|
||||||
/// Crea un nuevo [`TypedOpt`].
|
|
||||||
///
|
|
||||||
/// El componente se envuelve automáticamente en un [`Typed`] y se almacena.
|
|
||||||
pub fn new(component: C) -> Self {
|
|
||||||
TypedOpt(Some(Typed::with(component)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TypedOpt BUILDER ****************************************************************************
|
|
||||||
|
|
||||||
/// Establece un componente nuevo, o lo vacía.
|
|
||||||
///
|
|
||||||
/// Si se proporciona `Some(component)`, se guarda como [`Typed`]; y si es `None`, se limpia.
|
|
||||||
#[builder_fn]
|
|
||||||
pub fn with_component(mut self, component: Option<C>) -> Self {
|
|
||||||
self.0 = component.map(Typed::with);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
// TypedOpt GETTERS ****************************************************************************
|
|
||||||
|
|
||||||
/// Devuelve un clon (incrementa el contador `Arc`) de [`Typed<C>`], si existe.
|
|
||||||
pub fn get(&self) -> Option<Typed<C>> {
|
|
||||||
self.0.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TypedOpt RENDER *****************************************************************************
|
|
||||||
|
|
||||||
/// Renderiza el componente, si existe.
|
|
||||||
pub fn render(&self, cx: &mut Context) -> Markup {
|
|
||||||
if let Some(component) = &self.0 {
|
|
||||||
component.render(cx)
|
|
||||||
} else {
|
|
||||||
html! {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -50,14 +50,13 @@ pub type OptionClasses = AttrClasses;
|
||||||
|
|
||||||
use crate::{core, AutoDefault};
|
use crate::{core, AutoDefault};
|
||||||
|
|
||||||
/// **Obsoleto desde la versión 0.4.0**: usar [`TypedOpt`](crate::core::component::TypedOpt) en su
|
/// **Obsoleto desde la versión 0.4.0**: usar [`Typed`](crate::core::component::Typed) en su lugar.
|
||||||
/// lugar.
|
|
||||||
#[deprecated(
|
#[deprecated(
|
||||||
since = "0.4.0",
|
since = "0.4.0",
|
||||||
note = "Use `pagetop::core::component::TypedOpt` instead"
|
note = "Use `pagetop::core::component::Typed` instead"
|
||||||
)]
|
)]
|
||||||
#[allow(type_alias_bounds)]
|
#[allow(type_alias_bounds)]
|
||||||
pub type OptionComponent<C: core::component::Component> = core::component::TypedOpt<C>;
|
pub type OptionComponent<C: core::component::Component> = core::component::Typed<C>;
|
||||||
|
|
||||||
/// Prepara contenido HTML para su conversión a [`Markup`].
|
/// Prepara contenido HTML para su conversión a [`Markup`].
|
||||||
///
|
///
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue