x_bow/impls/stdlib/
hash_map.rs

1use std::{
2    cell::{Ref, RefMut},
3    collections::HashMap,
4    fmt::Debug,
5    hash::Hash,
6    ops::Deref,
7};
8
9use crate::{impls::leaf::LeafPathBuilder, path::Path, trackable::Trackable};
10
11#[derive(x_bow_macros::IntoPath)]
12#[into_path(prefix = crate::trackable)]
13pub struct HashMapPathBuilder<K: Eq + Clone + Hash, V, P: Path<Out = HashMap<K, V>>> {
14    inner_path: P,
15}
16
17impl<K: Eq + Clone + Hash, V, P: Path<Out = HashMap<K, V>>> Deref for HashMapPathBuilder<K, V, P> {
18    type Target = P;
19
20    fn deref(&self) -> &Self::Target {
21        &self.inner_path
22    }
23}
24
25impl<K: Eq + Clone + Hash, V> Trackable for HashMap<K, V> {
26    type PathBuilder<P: Path<Out = Self>> = HashMapPathBuilder<K, V, P>;
27
28    fn new_path_builder<P: Path<Out = Self>>(parent: P) -> Self::PathBuilder<P> {
29        HashMapPathBuilder { inner_path: parent }
30    }
31}
32
33impl<K: Eq + Clone + Hash, V, P: Path<Out = HashMap<K, V>> + Clone> Clone
34    for HashMapPathBuilder<K, V, P>
35{
36    fn clone(&self) -> Self {
37        Self {
38            inner_path: self.inner_path.clone(),
39        }
40    }
41}
42
43impl<K: Eq + Clone + Hash, V, P: Path<Out = HashMap<K, V>> + Copy> Copy
44    for HashMapPathBuilder<K, V, P>
45{
46}
47
48impl<K: Eq + Clone + Hash, V: Trackable, P: Path<Out = HashMap<K, V>>> HashMapPathBuilder<K, V, P> {
49    pub fn key(self, key: K) -> V::PathBuilder<HashMapKeyMapper<K, V, P>> {
50        V::new_path_builder(HashMapKeyMapper {
51            parent: self.inner_path,
52            key,
53        })
54    }
55}
56
57impl<K: Eq + Clone + Hash, V, P: Path<Out = HashMap<K, V>>> HashMapPathBuilder<K, V, P> {
58    pub fn key_shallow(self, key: K) -> LeafPathBuilder<HashMapKeyMapper<K, V, P>> {
59        LeafPathBuilder::new(HashMapKeyMapper {
60            parent: self.inner_path,
61            key,
62        })
63    }
64}
65
66pub struct HashMapKeyMapper<K: Eq + Clone + Hash, V, P: Path<Out = HashMap<K, V>>> {
67    parent: P,
68    key: K,
69}
70
71impl<K: Eq + Clone + Hash, V, P: Path<Out = HashMap<K, V>> + Clone> Clone
72    for HashMapKeyMapper<K, V, P>
73{
74    fn clone(&self) -> Self {
75        Self {
76            parent: self.parent.clone(),
77            key: self.key.clone(),
78        }
79    }
80}
81impl<K: Eq + Clone + Hash + Copy, V, P: Path<Out = HashMap<K, V>> + Copy> Copy
82    for HashMapKeyMapper<K, V, P>
83{
84}
85
86impl<K: Eq + Clone + Hash + Debug, V, P: Path<Out = HashMap<K, V>> + Debug> Debug
87    for HashMapKeyMapper<K, V, P>
88{
89    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90        self.parent.fmt(f)?;
91        f.write_fmt(format_args!("→(key {:?})", self.key))
92    }
93}
94
95impl<K: Eq + Clone + Hash, V, P: Path<Out = HashMap<K, V>>> Path for HashMapKeyMapper<K, V, P> {
96    type Out = V;
97
98    fn path_borrow(&self) -> Option<Ref<'_, Self::Out>> {
99        self.parent
100            .path_borrow()
101            .and_then(|r| Ref::filter_map(r, |hm| hm.get(&self.key)).ok())
102    }
103
104    fn path_borrow_mut(&self) -> Option<RefMut<'_, Self::Out>> {
105        self.parent
106            .path_borrow_mut()
107            .and_then(|r| RefMut::filter_map(r, |hm| hm.get_mut(&self.key)).ok())
108    }
109
110    fn visit_hashes(&self, visitor: &mut crate::hash_visitor::HashVisitor) {
111        self.parent.visit_hashes(visitor);
112        self.key.hash(&mut **visitor);
113        visitor.finish_one();
114    }
115
116    fn store_wakers(&self) -> &std::cell::RefCell<crate::wakers::StoreWakers> {
117        self.parent.store_wakers()
118    }
119}