facet_reflect/peek/
map.rs

1use facet_core::{MapDef, PtrConst, PtrMut};
2
3use super::Peek;
4
5/// Iterator over key-value pairs in a `PeekMap`
6pub struct PeekMapIter<'mem, 'facet, 'shape> {
7    map: PeekMap<'mem, 'facet, 'shape>,
8    iter: PtrMut<'mem>,
9}
10
11impl<'mem, 'facet, 'shape> Iterator for PeekMapIter<'mem, 'facet, 'shape> {
12    type Item = (Peek<'mem, 'facet, 'shape>, Peek<'mem, 'facet, 'shape>);
13
14    #[inline]
15    fn next(&mut self) -> Option<Self::Item> {
16        unsafe {
17            let next = (self.map.def.vtable.iter_vtable.next)(self.iter);
18            next.map(|(key_ptr, value_ptr)| {
19                (
20                    Peek::unchecked_new(key_ptr, self.map.def.k()),
21                    Peek::unchecked_new(value_ptr, self.map.def.v()),
22                )
23            })
24        }
25    }
26}
27
28impl<'mem, 'facet, 'shape> Drop for PeekMapIter<'mem, 'facet, 'shape> {
29    #[inline]
30    fn drop(&mut self) {
31        unsafe { (self.map.def.vtable.iter_vtable.dealloc)(self.iter) }
32    }
33}
34
35impl<'mem, 'facet, 'shape> IntoIterator for &'mem PeekMap<'mem, 'facet, 'shape> {
36    type Item = (Peek<'mem, 'facet, 'shape>, Peek<'mem, 'facet, 'shape>);
37    type IntoIter = PeekMapIter<'mem, 'facet, 'shape>;
38
39    #[inline]
40    fn into_iter(self) -> Self::IntoIter {
41        self.iter()
42    }
43}
44
45/// Lets you read from a map (implements read-only [`facet_core::MapVTable`] proxies)
46#[derive(Clone, Copy)]
47pub struct PeekMap<'mem, 'facet, 'shape> {
48    pub(crate) value: Peek<'mem, 'facet, 'shape>,
49
50    pub(crate) def: MapDef<'shape>,
51}
52
53impl<'mem, 'facet, 'shape> core::fmt::Debug for PeekMap<'mem, 'facet, 'shape> {
54    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
55        f.debug_struct("PeekMap").finish_non_exhaustive()
56    }
57}
58
59impl<'mem, 'facet, 'shape> PeekMap<'mem, 'facet, 'shape> {
60    /// Constructor
61    #[inline]
62    pub fn new(value: Peek<'mem, 'facet, 'shape>, def: MapDef<'shape>) -> Self {
63        Self { value, def }
64    }
65
66    /// Get the number of entries in the map
67    #[inline]
68    pub fn len(&self) -> usize {
69        unsafe { (self.def.vtable.len_fn)(self.value.data().thin().unwrap()) }
70    }
71
72    /// Returns true if the map is empty
73    #[inline]
74    pub fn is_empty(&self) -> bool {
75        self.len() == 0
76    }
77
78    /// Check if the map contains a key
79    #[inline]
80    pub fn contains_key(&self, key: &impl facet_core::Facet<'facet>) -> bool {
81        unsafe {
82            let key_ptr = PtrConst::new(key);
83            (self.def.vtable.contains_key_fn)(self.value.data().thin().unwrap(), key_ptr)
84        }
85    }
86
87    /// Get a value from the map for the given key
88    #[inline]
89    pub fn get<'k>(
90        &self,
91        key: &'k impl facet_core::Facet<'facet>,
92    ) -> Option<Peek<'mem, 'facet, 'shape>> {
93        unsafe {
94            let key_ptr = PtrConst::new(key);
95            let value_ptr =
96                (self.def.vtable.get_value_ptr_fn)(self.value.data().thin().unwrap(), key_ptr)?;
97            Some(Peek::unchecked_new(value_ptr, self.def.v()))
98        }
99    }
100
101    /// Returns an iterator over the key-value pairs in the map
102    #[inline]
103    pub fn iter(self) -> PeekMapIter<'mem, 'facet, 'shape> {
104        let iter_init_with_value_fn = self.def.vtable.iter_vtable.init_with_value.unwrap();
105        let iter = unsafe { iter_init_with_value_fn(self.value.data().thin().unwrap()) };
106        PeekMapIter { map: self, iter }
107    }
108
109    /// Def getter
110    #[inline]
111    pub fn def(&self) -> MapDef<'shape> {
112        self.def
113    }
114}