add some utilities around AnyValueRc
This commit is contained in:
1 parent
0c0158f62d
commit
0813d531f1
5 files changed
+49
-12
No files matched your search
@@ -70,7 +70,7 @@ pub(crate) mod innerlude {
|
||||
}
|
||||
|
||||
pub use crate::innerlude::{
|
||||
fc_to_builder, AnyValueBox, Attribute, AttributeValue, Component, DynamicNode, Element,
|
||||
fc_to_builder, AnyValueRc, Attribute, AttributeValue, Component, DynamicNode, Element,
|
||||
ElementId, Event, Fragment, IntoAttributeValue, IntoDynNode, LazyNodes, Mutation, Mutations,
|
||||
Properties, RenderReturn, Scope, ScopeId, ScopeState, Scoped, SuspenseContext, TaskId,
|
||||
Template, TemplateAttribute, TemplateNode, VComponent, VNode, VText, VirtualDom,
|
||||
|
||||
@@ -338,7 +338,7 @@ pub enum AttributeValue<'a> {
|
||||
Listener(ListenerCb<'a>),
|
||||
|
||||
/// An arbitrary value that implements PartialEq and is static
|
||||
Any(AnyValueBox),
|
||||
Any(AnyValueRc),
|
||||
|
||||
/// A "none" value, resulting in the removal of an attribute from the dom
|
||||
None,
|
||||
@@ -375,10 +375,47 @@ impl<'de, 'a> serde::Deserialize<'de> for ListenerCb<'a> {
|
||||
|
||||
/// A boxed value that implements PartialEq and Any
|
||||
#[derive(Clone)]
|
||||
pub struct AnyValueBox(pub Rc<dyn AnyValue>);
|
||||
pub struct AnyValueRc(pub Rc<dyn AnyValue>);
|
||||
|
||||
impl PartialEq for AnyValueRc {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.any_cmp(other.0.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl AnyValueRc {
|
||||
/// Returns a reference to the inner value without checking the type.
|
||||
pub fn downcast_ref_unchecked<T: Any + PartialEq>(&self) -> &T {
|
||||
unsafe { &*(self.0.as_ref() as *const dyn AnyValue as *const T) }
|
||||
}
|
||||
|
||||
/// Returns a reference to the inner value.
|
||||
pub fn downcast_ref<T: Any + PartialEq>(&self) -> Option<&T> {
|
||||
if self.0.our_typeid() == TypeId::of::<T>() {
|
||||
Some(self.downcast_ref_unchecked())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the inner value is of type `T`.
|
||||
pub fn is<T: Any + PartialEq>(&self) -> bool {
|
||||
self.0.our_typeid() == TypeId::of::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_any_value_rc() {
|
||||
let a = AnyValueRc(Rc::new(1i32));
|
||||
assert!(a.is::<i32>());
|
||||
assert!(!a.is::<i64>());
|
||||
assert_eq!(a.downcast_ref::<i32>(), Some(&1i32));
|
||||
assert_eq!(a.downcast_ref::<i64>(), None);
|
||||
assert_eq!(a.downcast_ref_unchecked::<i32>(), &1i32);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl serde::Serialize for AnyValueBox {
|
||||
impl serde::Serialize for AnyValueRc {
|
||||
fn serialize<S>(&self, _: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
@@ -388,7 +425,7 @@ impl serde::Serialize for AnyValueBox {
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl<'de> serde::Deserialize<'de> for AnyValueBox {
|
||||
impl<'de> serde::Deserialize<'de> for AnyValueRc {
|
||||
fn deserialize<D>(_: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
@@ -419,7 +456,7 @@ impl<'a> PartialEq for AttributeValue<'a> {
|
||||
(Self::Int(l0), Self::Int(r0)) => l0 == r0,
|
||||
(Self::Bool(l0), Self::Bool(r0)) => l0 == r0,
|
||||
(Self::Listener(_), Self::Listener(_)) => true,
|
||||
(Self::Any(l0), Self::Any(r0)) => l0.0.any_cmp(r0.0.as_ref()),
|
||||
(Self::Any(l0), Self::Any(r0)) => l0 == r0,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -642,7 +679,7 @@ impl<'a> IntoAttributeValue<'a> for Arguments<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoAttributeValue<'a> for AnyValueBox {
|
||||
impl<'a> IntoAttributeValue<'a> for AnyValueRc {
|
||||
fn into_value(self, _: &'a Bump) -> AttributeValue<'a> {
|
||||
AttributeValue::Any(self)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{state::State, tree::NodeId};
|
||||
use dioxus_core::{AnyValueBox, AttributeValue, ElementId};
|
||||
use dioxus_core::{AnyValueRc, AttributeValue, ElementId};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use std::fmt::Debug;
|
||||
|
||||
@@ -79,7 +79,7 @@ pub enum OwnedAttributeValue {
|
||||
Float(f64),
|
||||
Int(i64),
|
||||
Bool(bool),
|
||||
Any(AnyValueBox),
|
||||
Any(AnyValueRc),
|
||||
None,
|
||||
}
|
||||
|
||||
|
||||
@@ -185,9 +185,9 @@ fn render_vdom(
|
||||
let rdom = rdom.borrow();
|
||||
let mut taffy = taffy.lock().expect("taffy lock poisoned");
|
||||
// size is guaranteed to not change when rendering
|
||||
resize(frame.size(), &mut *taffy, &rdom);
|
||||
resize(frame.size(), &mut taffy, &rdom);
|
||||
let root = &rdom[NodeId(0)];
|
||||
render::render_vnode(frame, &*taffy, &rdom, root, cfg, Point::ZERO);
|
||||
render::render_vnode(frame, &taffy, &rdom, root, cfg, Point::ZERO);
|
||||
})?;
|
||||
} else {
|
||||
let rdom = rdom.borrow();
|
||||
|
||||
@@ -89,7 +89,7 @@ impl<'a> ElementRef<'a> {
|
||||
.ok();
|
||||
layout.map(|layout| Layout {
|
||||
order: layout.order,
|
||||
size: layout.size.map(|v| layout_to_screen_space(v)),
|
||||
size: layout.size.map(layout_to_screen_space),
|
||||
location: Point {
|
||||
x: layout_to_screen_space(layout.location.x),
|
||||
y: layout_to_screen_space(layout.location.y),
|
||||
|
||||
Reference in new issue
Block a user