perseus/state/rx_collections/
rx_hash_map.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 RxHashMap<K, V>(HashMap<K, V>)
17where
18 K: Clone + Eq + Hash,
19 V: Clone + 'static;
22#[derive(Clone, Debug, PartialEq, Eq)]
24pub struct RxHashMapRx<K, V>(RcSignal<HashMap<K, RcSignal<V>>>)
25where
26 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
27 V: Clone + Serialize + DeserializeOwned + 'static;
28
29impl<K, V> MakeRx for RxHashMap<K, V>
31where
32 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
33 V: Clone + Serialize + DeserializeOwned + 'static,
34{
35 type Rx = RxHashMapRx<K, V>;
36
37 fn make_rx(self) -> Self::Rx {
38 RxHashMapRx(create_rc_signal(
39 self.0
40 .into_iter()
41 .map(|(k, v)| (k, create_rc_signal(v)))
42 .collect(),
43 ))
44 }
45}
46impl<K, V> MakeUnrx for RxHashMapRx<K, V>
47where
48 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
49 V: Clone + Serialize + DeserializeOwned + 'static,
50{
51 type Unrx = RxHashMap<K, V>;
52
53 fn make_unrx(self) -> Self::Unrx {
54 let map = (*self.0.get_untracked()).clone();
55 RxHashMap(
56 map.into_iter()
57 .map(|(k, v)| (k, (*v.get_untracked()).clone()))
58 .collect(),
59 )
60 }
61
62 #[cfg(any(client, doc))]
63 fn compute_suspense(&self, _cx: Scope) {}
64}
65impl<K, V> Deref for RxHashMap<K, V>
67where
68 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
69 V: Clone + Serialize + DeserializeOwned + 'static,
70{
71 type Target = HashMap<K, V>;
72
73 fn deref(&self) -> &Self::Target {
74 &self.0
75 }
76}
77impl<K, V> Deref for RxHashMapRx<K, V>
78where
79 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
80 V: Clone + Serialize + DeserializeOwned + 'static,
81{
82 type Target = RcSignal<HashMap<K, RcSignal<V>>>;
83
84 fn deref(&self) -> &Self::Target {
85 &self.0
86 }
87}
88impl<K, V> From<HashMap<K, V>> for RxHashMap<K, V>
90where
91 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
92 V: Clone + Serialize + DeserializeOwned + 'static,
93{
94 fn from(value: HashMap<K, V>) -> Self {
95 Self(value)
96 }
97}
98
99impl<K, V> Freeze for RxHashMapRx<K, V>
101where
102 K: Clone + Serialize + DeserializeOwned + Eq + Hash,
103 V: Clone + Serialize + DeserializeOwned + 'static,
104{
105 fn freeze(&self) -> String {
106 let unrx = Self(self.0.clone()).make_unrx();
107 serde_json::to_string(&unrx).unwrap()
109 }
110}