Skip to main content

facet_reflect/peek/
map.rs

1use facet_core::{MapDef, PtrMut};
2
3use crate::{ReflectError, ReflectErrorKind};
4
5use super::Peek;
6
7/// Iterator over key-value pairs in a `PeekMap`
8pub struct PeekMapIter<'mem, 'facet> {
9    map: PeekMap<'mem, 'facet>,
10    iter: PtrMut,
11}
12
13impl<'mem, 'facet> Iterator for PeekMapIter<'mem, 'facet> {
14    type Item = (Peek<'mem, 'facet>, Peek<'mem, 'facet>);
15
16    #[inline]
17    fn next(&mut self) -> Option<Self::Item> {
18        unsafe {
19            let next = (self.map.def.vtable.iter_vtable.next)(self.iter);
20            next.map(|(key_ptr, value_ptr)| {
21                (
22                    Peek::unchecked_new(key_ptr, self.map.def.k()),
23                    Peek::unchecked_new(value_ptr, self.map.def.v()),
24                )
25            })
26        }
27    }
28}
29
30impl<'mem, 'facet> Drop for PeekMapIter<'mem, 'facet> {
31    #[inline]
32    fn drop(&mut self) {
33        unsafe { (self.map.def.vtable.iter_vtable.dealloc)(self.iter) }
34    }
35}
36
37impl<'mem, 'facet> IntoIterator for &'mem PeekMap<'mem, 'facet> {
38    type Item = (Peek<'mem, 'facet>, Peek<'mem, 'facet>);
39    type IntoIter = PeekMapIter<'mem, 'facet>;
40
41    #[inline]
42    fn into_iter(self) -> Self::IntoIter {
43        self.iter()
44    }
45}
46
47/// Lets you read from a map (implements read-only [`facet_core::MapVTable`] proxies)
48#[derive(Clone, Copy)]
49pub struct PeekMap<'mem, 'facet> {
50    value: Peek<'mem, 'facet>,
51
52    def: MapDef,
53}
54
55impl<'mem, 'facet> core::fmt::Debug for PeekMap<'mem, 'facet> {
56    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
57        f.debug_struct("PeekMap").finish_non_exhaustive()
58    }
59}
60
61impl<'mem, 'facet> PeekMap<'mem, 'facet> {
62    /// Constructor
63    ///
64    /// # Safety
65    ///
66    /// The caller must ensure that `def` contains valid vtable function pointers that:
67    /// - Correctly implement the map operations for the actual type
68    /// - Do not cause undefined behavior when called
69    /// - Return pointers within valid memory bounds
70    /// - Match the key and value types specified in `def.k()` and `def.v()`
71    ///
72    /// Violating these requirements can lead to memory safety issues.
73    #[inline]
74    pub const unsafe fn new(value: Peek<'mem, 'facet>, def: MapDef) -> Self {
75        Self { value, def }
76    }
77
78    fn err(&self, kind: ReflectErrorKind) -> ReflectError {
79        self.value.err(kind)
80    }
81
82    /// Get the number of entries in the map
83    #[inline]
84    pub fn len(&self) -> usize {
85        unsafe { (self.def.vtable.len)(self.value.data()) }
86    }
87
88    /// Returns true if the map is empty
89    #[inline]
90    pub fn is_empty(&self) -> bool {
91        self.len() == 0
92    }
93
94    /// Check if the map contains a key
95    #[inline]
96    pub fn contains_key(&self, key: &impl facet_core::Facet<'facet>) -> Result<bool, ReflectError> {
97        self.contains_key_peek(Peek::new(key))
98    }
99
100    /// Get a value from the map for the given key
101    #[inline]
102    pub fn get<'k>(
103        &self,
104        key: &'k impl facet_core::Facet<'facet>,
105    ) -> Result<Option<Peek<'mem, 'facet>>, ReflectError> {
106        self.get_peek(Peek::new(key))
107    }
108
109    /// Check if the map contains a key
110    #[inline]
111    pub fn contains_key_peek(&self, key: Peek<'_, 'facet>) -> Result<bool, ReflectError> {
112        if self.def.k() == key.shape {
113            return Ok(unsafe { (self.def.vtable.contains_key)(self.value.data(), key.data()) });
114        }
115
116        Err(self.err(ReflectErrorKind::WrongShape {
117            expected: self.def.k(),
118            actual: key.shape,
119        }))
120    }
121
122    /// Get a value from the map for the given key
123    #[inline]
124    pub fn get_peek(
125        &self,
126        key: Peek<'_, 'facet>,
127    ) -> Result<Option<Peek<'mem, 'facet>>, ReflectError> {
128        if self.def.k() == key.shape {
129            return Ok(unsafe {
130                let value_ptr = (self.def.vtable.get_value_ptr)(self.value.data(), key.data());
131                if value_ptr.is_null() {
132                    return Ok(None);
133                }
134                let value_ptr = facet_core::PtrConst::new_sized(value_ptr);
135                Some(Peek::unchecked_new(value_ptr, self.def.v()))
136            });
137        }
138
139        Err(self.err(ReflectErrorKind::WrongShape {
140            expected: self.def.k(),
141            actual: key.shape,
142        }))
143    }
144
145    /// Returns an iterator over the key-value pairs in the map
146    #[inline]
147    pub fn iter(self) -> PeekMapIter<'mem, 'facet> {
148        let iter_init_with_value_fn = self.def.vtable.iter_vtable.init_with_value.unwrap();
149        let iter = unsafe { iter_init_with_value_fn(self.value.data()) };
150        PeekMapIter { map: self, iter }
151    }
152
153    /// Def getter
154    #[inline]
155    pub const fn def(&self) -> MapDef {
156        self.def
157    }
158}