use crate::state::{Freeze, MakeRx, MakeUnrx};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::collections::HashMap;
use std::hash::Hash;
use std::ops::Deref;
#[cfg(any(client, doc))]
use sycamore::prelude::Scope;
use sycamore::reactive::{create_rc_signal, RcSignal};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct RxHashMap<K, V>(HashMap<K, V>)
where
K: Clone + Eq + Hash,
V: Clone + 'static;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RxHashMapRx<K, V>(RcSignal<HashMap<K, RcSignal<V>>>)
where
K: Clone + Serialize + DeserializeOwned + Eq + Hash,
V: Clone + Serialize + DeserializeOwned + 'static;
impl<K, V> MakeRx for RxHashMap<K, V>
where
K: Clone + Serialize + DeserializeOwned + Eq + Hash,
V: Clone + Serialize + DeserializeOwned + 'static,
{
type Rx = RxHashMapRx<K, V>;
fn make_rx(self) -> Self::Rx {
RxHashMapRx(create_rc_signal(
self.0
.into_iter()
.map(|(k, v)| (k, create_rc_signal(v)))
.collect(),
))
}
}
impl<K, V> MakeUnrx for RxHashMapRx<K, V>
where
K: Clone + Serialize + DeserializeOwned + Eq + Hash,
V: Clone + Serialize + DeserializeOwned + 'static,
{
type Unrx = RxHashMap<K, V>;
fn make_unrx(self) -> Self::Unrx {
let map = (*self.0.get_untracked()).clone();
RxHashMap(
map.into_iter()
.map(|(k, v)| (k, (*v.get_untracked()).clone()))
.collect(),
)
}
#[cfg(any(client, doc))]
fn compute_suspense(&self, _cx: Scope) {}
}
impl<K, V> Deref for RxHashMap<K, V>
where
K: Clone + Serialize + DeserializeOwned + Eq + Hash,
V: Clone + Serialize + DeserializeOwned + 'static,
{
type Target = HashMap<K, V>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<K, V> Deref for RxHashMapRx<K, V>
where
K: Clone + Serialize + DeserializeOwned + Eq + Hash,
V: Clone + Serialize + DeserializeOwned + 'static,
{
type Target = RcSignal<HashMap<K, RcSignal<V>>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<K, V> From<HashMap<K, V>> for RxHashMap<K, V>
where
K: Clone + Serialize + DeserializeOwned + Eq + Hash,
V: Clone + Serialize + DeserializeOwned + 'static,
{
fn from(value: HashMap<K, V>) -> Self {
Self(value)
}
}
impl<K, V> Freeze for RxHashMapRx<K, V>
where
K: Clone + Serialize + DeserializeOwned + Eq + Hash,
V: Clone + Serialize + DeserializeOwned + 'static,
{
fn freeze(&self) -> String {
let unrx = Self(self.0.clone()).make_unrx();
serde_json::to_string(&unrx).unwrap()
}
}