use std::cell::{Ref, RefCell};
use std::collections::HashMap;
use std::hash::Hash;
use std::rc::Rc;
use yew::prelude::*;
use super::use_update;
pub struct UseMapHandle<K, V> {
inner: Rc<RefCell<HashMap<K, V>>>,
update: Rc<dyn Fn()>,
}
impl<K, V> UseMapHandle<K, V> {
pub fn current(&self) -> Ref<HashMap<K, V>> {
self.inner.borrow()
}
pub fn set(&self, map: HashMap<K, V>) {
*self.inner.borrow_mut() = map;
(self.update)();
}
pub fn insert(&self, k: K, v: V) -> Option<V>
where
K: Eq + Hash,
{
let v = self.inner.borrow_mut().insert(k, v);
(self.update)();
v
}
pub fn update(&self, k: &K, v: V)
where
K: Eq + Hash,
{
if let Some(value) = self.inner.borrow_mut().get_mut(k) {
*value = v;
}
(self.update)();
}
pub fn remove(&self, k: &K) -> Option<V>
where
K: Eq + Hash,
{
let v = self.inner.borrow_mut().remove(k);
(self.update)();
v
}
pub fn retain<F>(&self, f: F)
where
K: Eq + Hash,
F: FnMut(&K, &mut V) -> bool,
{
self.inner.borrow_mut().retain(f);
(self.update)();
}
pub fn clear(&self) {
self.inner.borrow_mut().clear();
(self.update)();
}
}
impl<K, V> Clone for UseMapHandle<K, V> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
update: self.update.clone(),
}
}
}
impl<K, V> PartialEq for UseMapHandle<K, V>
where
K: Eq + Hash,
V: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
*self.inner == *other.inner
}
}
#[hook]
pub fn use_map<K, V>(initial_value: HashMap<K, V>) -> UseMapHandle<K, V>
where
K: 'static,
V: 'static,
{
let inner = use_mut_ref(|| initial_value);
let update = use_update();
UseMapHandle { inner, update }
}