perseus/state/rx_collections/
rx_hash_map_nested.rs1use crate::state::{Freeze, MakeRx, MakeUnrx};
2use serde::{de::DeserializeOwned, Deserialize, Serialize};
3use std::collections::HashMap;
4use std::hash::Hash;
5use std::ops::Deref;
6#[cfg(any(client, doc))]
7use sycamore::prelude::Scope;
8use sycamore::reactive::{create_rc_signal, RcSignal};
9
10#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
16pub struct RxHashMapNested<K, V>(HashMap<K, V>)
17where
18 K: Clone + Eq + Hash,
19 V: MakeRx + 'static,
22 V::Rx: MakeUnrx<Unrx = V> + Freeze + Clone;
23#[derive(Clone, Debug, PartialEq, Eq)]
25pub struct RxHashMapNestedRx<K, V>(RcSignal<HashMap<K, V::Rx>>)
26where
27 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
28 V: MakeRx + Serialize + DeserializeOwned + 'static,
29 V::Rx: MakeUnrx<Unrx = V> + Freeze + Clone;
30
31impl<K, V> MakeRx for RxHashMapNested<K, V>
33where
34 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
35 V: MakeRx + Serialize + DeserializeOwned + 'static,
36 V::Rx: MakeUnrx<Unrx = V> + Freeze + Clone,
37{
38 type Rx = RxHashMapNestedRx<K, V>;
39
40 fn make_rx(self) -> Self::Rx {
41 RxHashMapNestedRx(create_rc_signal(
42 self.0.into_iter().map(|(k, v)| (k, v.make_rx())).collect(),
43 ))
44 }
45}
46impl<K, V> MakeUnrx for RxHashMapNestedRx<K, V>
47where
48 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
49 V: MakeRx + Serialize + DeserializeOwned + 'static,
50 V::Rx: MakeUnrx<Unrx = V> + Freeze + Clone,
51{
52 type Unrx = RxHashMapNested<K, V>;
53
54 fn make_unrx(self) -> Self::Unrx {
55 let map = (*self.0.get_untracked()).clone();
56 RxHashMapNested(map.into_iter().map(|(k, v)| (k, v.make_unrx())).collect())
57 }
58
59 #[cfg(any(client, doc))]
60 fn compute_suspense(&self, cx: Scope) {
61 for elem in self.0.get_untracked().values() {
64 elem.compute_suspense(cx);
65 }
66 }
67}
68impl<K, V> Deref for RxHashMapNested<K, V>
70where
71 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
72 V: MakeRx + Serialize + DeserializeOwned + 'static,
73 V::Rx: MakeUnrx<Unrx = V> + Freeze + Clone,
74{
75 type Target = HashMap<K, V>;
76
77 fn deref(&self) -> &Self::Target {
78 &self.0
79 }
80}
81impl<K, V> Deref for RxHashMapNestedRx<K, V>
82where
83 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
84 V: MakeRx + Serialize + DeserializeOwned + 'static,
85 V::Rx: MakeUnrx<Unrx = V> + Freeze + Clone,
86{
87 type Target = RcSignal<HashMap<K, V::Rx>>;
88
89 fn deref(&self) -> &Self::Target {
90 &self.0
91 }
92}
93impl<K, V> From<HashMap<K, V>> for RxHashMapNested<K, V>
95where
96 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
97 V: MakeRx + Serialize + DeserializeOwned + 'static,
98 V::Rx: MakeUnrx<Unrx = V> + Freeze + Clone,
99{
100 fn from(value: HashMap<K, V>) -> Self {
101 Self(value)
102 }
103}
104
105impl<K, V> Freeze for RxHashMapNestedRx<K, V>
107where
108 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
109 V: MakeRx + Serialize + DeserializeOwned + 'static,
110 V::Rx: MakeUnrx<Unrx = V> + Freeze + Clone,
111{
112 fn freeze(&self) -> String {
113 let unrx = Self(self.0.clone()).make_unrx();
114 serde_json::to_string(&unrx).unwrap()
116 }
117}