wasm_react/
prop_container.rs1use crate::hooks::{DeferredValue, Memo, RefContainer, State};
2use std::{
3 cell::{Ref, RefCell},
4 ops::Deref,
5 rc::Rc,
6};
7
8#[non_exhaustive]
10#[derive(Debug)]
11pub enum PropContainerRef<'a, T> {
12 #[allow(missing_docs)]
13 Simple(&'a T),
14 #[allow(missing_docs)]
15 Ref(Ref<'a, T>),
16}
17
18impl<T> PropContainerRef<'_, T> {
19 pub fn clone(orig: &Self) -> Self {
21 match orig {
22 PropContainerRef::Simple(x) => PropContainerRef::Simple(x),
23 PropContainerRef::Ref(x) => PropContainerRef::Ref(Ref::clone(x)),
24 }
25 }
26}
27
28impl<T> Deref for PropContainerRef<'_, T> {
29 type Target = T;
30
31 fn deref(&self) -> &Self::Target {
32 match &self {
33 PropContainerRef::Simple(x) => x,
34 PropContainerRef::Ref(x) => x.deref(),
35 }
36 }
37}
38
39macro_rules! define_value_container {
40 {
41 $(
42 $Variant:ident($id:ident: $Ty:ty) => $RefVariant:ident($expr:expr) $(,)?
43 )*
44 } => {
45 #[non_exhaustive]
50 #[derive(Debug)]
51 pub enum PropContainer<T> {
52 $(
53 #[allow(missing_docs)]
54 $Variant($Ty),
55 )*
56 }
57
58 impl<T: 'static> PropContainer<T> {
59 pub fn value(&self) -> PropContainerRef<'_, T> {
61 match self {
62 $( Self::$Variant($id) => PropContainerRef::$RefVariant($expr), )*
63 }
64 }
65 }
66
67 impl<T> Clone for PropContainer<T> {
68 fn clone(&self) -> Self {
69 match self {
70 $( Self::$Variant(x) => Self::$Variant(x.clone()), )*
71 }
72 }
73 }
74
75 $(
76 impl<T> From<$Ty> for PropContainer<T> {
77 fn from(value: $Ty) -> Self {
78 Self::$Variant(value)
79 }
80 }
81 )*
82 };
83}
84
85define_value_container! {
86 Rc(x: Rc<T>) => Simple(x.deref()),
87 RcRefCell(x: Rc<RefCell<T>>) => Ref(x.borrow()),
88 RefContainer(x: RefContainer<T>) => Ref(x.current()),
89 State(x: State<T>) => Ref(x.value()),
90 Memo(x: Memo<T>) => Ref(x.value()),
91 DeferredValue(x: DeferredValue<T>) => Ref(x.value()),
92}
93
94impl<T: PartialEq + 'static> PartialEq for PropContainer<T> {
95 fn eq(&self, other: &Self) -> bool {
96 T::eq(&self.value(), &other.value())
97 }
98}
99
100impl<T: PartialEq + 'static> PartialEq<T> for PropContainer<T> {
101 fn eq(&self, other: &T) -> bool {
102 T::eq(&self.value(), other)
103 }
104}
105
106impl<T> From<T> for PropContainer<T> {
107 fn from(value: T) -> Self {
108 Self::from(Rc::new(value))
109 }
110}