use crate::hooks::use_signal::{Signal, use_signal};
use std::collections::HashMap;
use std::hash::Hash;
#[derive(Clone)]
pub struct MapHandle<K, V> {
signal: Signal<HashMap<K, V>>,
}
impl<K, V> MapHandle<K, V>
where
K: Clone + Eq + Hash + Send + Sync + 'static,
V: Clone + Send + Sync + 'static,
{
pub fn get_all(&self) -> HashMap<K, V> {
self.signal.get()
}
pub fn len(&self) -> usize {
self.signal.with(|m| m.len())
}
pub fn is_empty(&self) -> bool {
self.signal.with(|m| m.is_empty())
}
pub fn get(&self, key: &K) -> Option<V> {
self.signal.with(|m| m.get(key).cloned())
}
pub fn insert(&self, key: K, value: V) -> Option<V> {
let mut result = None;
self.signal.update(|m| {
result = m.insert(key, value);
});
result
}
pub fn remove(&self, key: &K) -> Option<V> {
let mut result = None;
self.signal.update(|m| {
result = m.remove(key);
});
result
}
pub fn contains_key(&self, key: &K) -> bool {
self.signal.with(|m| m.contains_key(key))
}
pub fn clear(&self) {
self.signal.update(|m| m.clear());
}
pub fn set(&self, map: HashMap<K, V>) {
self.signal.set(map);
}
pub fn keys(&self) -> Vec<K> {
self.signal.with(|m| m.keys().cloned().collect())
}
pub fn values(&self) -> Vec<V> {
self.signal.with(|m| m.values().cloned().collect())
}
pub fn update_value<F>(&self, key: &K, f: F)
where
F: FnOnce(&mut V),
{
self.signal.update(|m| {
if let Some(v) = m.get_mut(key) {
f(v);
}
});
}
pub fn get_or_insert(&self, key: K, default: V) -> V {
if let Some(v) = self.get(&key) {
v
} else {
self.insert(key.clone(), default.clone());
default
}
}
pub fn merge(&self, other: HashMap<K, V>) {
self.signal.update(|m| {
m.extend(other);
});
}
}
pub fn use_map<K, V>(initial: Vec<(K, V)>) -> MapHandle<K, V>
where
K: Clone + Eq + Hash + Send + Sync + 'static,
V: Clone + Send + Sync + 'static,
{
let signal = use_signal(|| initial.into_iter().collect());
MapHandle { signal }
}
pub fn use_map_empty<K, V>() -> MapHandle<K, V>
where
K: Clone + Eq + Hash + Send + Sync + 'static,
V: Clone + Send + Sync + 'static,
{
use_map(Vec::new())
}
pub fn use_map_from<K, V>(map: HashMap<K, V>) -> MapHandle<K, V>
where
K: Clone + Eq + Hash + Send + Sync + 'static,
V: Clone + Send + Sync + 'static,
{
let signal = use_signal(|| map);
MapHandle { signal }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_use_map_compiles() {
fn _test() {
let map = use_map(vec![("a", 1), ("b", 2)]);
map.insert("c", 3);
map.remove(&"a");
let _ = map.get(&"b");
let _ = map.len();
let _ = map.is_empty();
let _ = map.contains_key(&"c");
}
}
#[test]
fn test_use_map_empty_compiles() {
fn _test() {
let map: MapHandle<String, i32> = use_map_empty();
map.insert("key".to_string(), 42);
}
}
#[test]
fn test_map_operations_compile() {
fn _test() {
let map = use_map(vec![("x", 10)]);
let _ = map.keys();
let _ = map.values();
map.update_value(&"x", |v| *v += 1);
let _ = map.get_or_insert("y", 20);
map.clear();
}
}
}