facet_core/types/def/
map.rs

1use crate::ptr::{PtrConst, PtrMut, PtrUninit};
2
3use super::Shape;
4
5/// Fields for map types
6#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
7#[repr(C)]
8#[non_exhaustive]
9pub struct MapDef {
10    /// vtable for interacting with the map
11    pub vtable: &'static MapVTable,
12    /// shape of the keys in the map
13    pub k: fn() -> &'static Shape,
14    /// shape of the values in the map
15    pub v: fn() -> &'static Shape,
16}
17
18impl MapDef {
19    /// Returns a builder for MapDef
20    pub const fn builder() -> MapDefBuilder {
21        MapDefBuilder::new()
22    }
23
24    /// Returns the shape of the keys of the map
25    pub fn k(&self) -> &'static Shape {
26        (self.k)()
27    }
28
29    /// Returns the shape of the values of the map
30    pub fn v(&self) -> &'static Shape {
31        (self.v)()
32    }
33}
34
35/// Builder for MapDef
36pub struct MapDefBuilder {
37    vtable: Option<&'static MapVTable>,
38    k: Option<fn() -> &'static Shape>,
39    v: Option<fn() -> &'static Shape>,
40}
41
42impl MapDefBuilder {
43    /// Creates a new MapDefBuilder
44    #[allow(clippy::new_without_default)]
45    pub const fn new() -> Self {
46        Self {
47            vtable: None,
48            k: None,
49            v: None,
50        }
51    }
52
53    /// Sets the vtable for the MapDef
54    pub const fn vtable(mut self, vtable: &'static MapVTable) -> Self {
55        self.vtable = Some(vtable);
56        self
57    }
58
59    /// Sets the key shape for the MapDef
60    pub const fn k(mut self, k: fn() -> &'static Shape) -> Self {
61        self.k = Some(k);
62        self
63    }
64
65    /// Sets the value shape for the MapDef
66    pub const fn v(mut self, v: fn() -> &'static Shape) -> Self {
67        self.v = Some(v);
68        self
69    }
70
71    /// Builds the MapDef
72    pub const fn build(self) -> MapDef {
73        MapDef {
74            vtable: self.vtable.unwrap(),
75            k: self.k.unwrap(),
76            v: self.v.unwrap(),
77        }
78    }
79}
80
81/// Initialize a map in place with a given capacity
82///
83/// # Safety
84///
85/// The `map` parameter must point to uninitialized memory of sufficient size.
86/// The function must properly initialize the memory.
87pub type MapInitInPlaceWithCapacityFn =
88    for<'mem> unsafe fn(map: PtrUninit<'mem>, capacity: usize) -> PtrMut<'mem>;
89
90/// Insert a key-value pair into the map
91///
92/// # Safety
93///
94/// The `map` parameter must point to aligned, initialized memory of the correct type.
95/// `key` and `value` are moved out of (with [`core::ptr::read`]) — they should be deallocated
96/// afterwards (e.g. with [`core::mem::forget`]) but NOT dropped.
97pub type MapInsertFn =
98    for<'map, 'key, 'value> unsafe fn(map: PtrMut<'map>, key: PtrMut<'key>, value: PtrMut<'value>);
99
100/// Get the number of entries in the map
101///
102/// # Safety
103///
104/// The `map` parameter must point to aligned, initialized memory of the correct type.
105pub type MapLenFn = for<'map> unsafe fn(map: PtrConst<'map>) -> usize;
106
107/// Check if the map contains a key
108///
109/// # Safety
110///
111/// The `map` parameter must point to aligned, initialized memory of the correct type.
112pub type MapContainsKeyFn =
113    for<'map, 'key> unsafe fn(map: PtrConst<'map>, key: PtrConst<'key>) -> bool;
114
115/// Get pointer to a value for a given key, returns None if not found
116///
117/// # Safety
118///
119/// The `map` parameter must point to aligned, initialized memory of the correct type.
120pub type MapGetValuePtrFn =
121    for<'map, 'key> unsafe fn(map: PtrConst<'map>, key: PtrConst<'key>) -> Option<PtrConst<'map>>;
122
123/// Get an iterator over the map
124///
125/// # Safety
126///
127/// The `map` parameter must point to aligned, initialized memory of the correct type.
128pub type MapIterFn = for<'map> unsafe fn(map: PtrConst<'map>) -> PtrMut<'map>;
129
130/// Get the next key-value pair from the iterator
131///
132/// # Safety
133///
134/// The `iter` parameter must point to aligned, initialized memory of the correct type.
135pub type MapIterNextFn =
136    for<'iter> unsafe fn(iter: PtrMut<'iter>) -> Option<(PtrConst<'iter>, PtrConst<'iter>)>;
137
138/// Get the next key-value pair from the end of the iterator
139///
140/// # Safety
141///
142/// The `iter` parameter must point to aligned, initialized memory of the correct type.
143pub type MapIterNextBackFn =
144    for<'iter> unsafe fn(iter: PtrMut<'iter>) -> Option<(PtrConst<'iter>, PtrConst<'iter>)>;
145
146/// Deallocate the iterator
147///
148/// # Safety
149///
150/// The `iter` parameter must point to aligned, initialized memory of the correct type.
151pub type MapIterDeallocFn = for<'iter> unsafe fn(iter: PtrMut<'iter>);
152
153/// VTable for an iterator over a map
154#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
155#[repr(C)]
156#[non_exhaustive]
157pub struct MapIterVTable {
158    /// cf. [`MapIterNextFn`]
159    pub next: MapIterNextFn,
160
161    /// cf. [`MapIterNextBackFn`]
162    pub next_back: MapIterNextBackFn,
163
164    /// cf. [`MapIterDeallocFn`]
165    pub dealloc: MapIterDeallocFn,
166}
167
168impl MapIterVTable {
169    /// Returns a builder for MapIterVTable
170    pub const fn builder() -> MapIterVTableBuilder {
171        MapIterVTableBuilder::new()
172    }
173}
174
175/// Builds a [`MapIterVTable`]
176pub struct MapIterVTableBuilder {
177    next: Option<MapIterNextFn>,
178    next_back: Option<MapIterNextBackFn>,
179    dealloc: Option<MapIterDeallocFn>,
180}
181
182impl MapIterVTableBuilder {
183    /// Creates a new [`MapIterVTableBuilder`] with all fields set to `None`.
184    #[allow(clippy::new_without_default)]
185    pub const fn new() -> Self {
186        Self {
187            next: None,
188            next_back: None,
189            dealloc: None,
190        }
191    }
192
193    /// Sets the next field
194    pub const fn next(mut self, f: MapIterNextFn) -> Self {
195        self.next = Some(f);
196        self
197    }
198
199    /// Sets the next_back field
200    pub const fn next_back(mut self, f: MapIterNextBackFn) -> Self {
201        self.next_back = Some(f);
202        self
203    }
204
205    /// Sets the dealloc field
206    pub const fn dealloc(mut self, f: MapIterDeallocFn) -> Self {
207        self.dealloc = Some(f);
208        self
209    }
210
211    /// Builds the [`MapIterVTable`] from the current state of the builder.
212    ///
213    /// # Panics
214    ///
215    /// This method will panic if any of the required fields are `None`.
216    pub const fn build(self) -> MapIterVTable {
217        MapIterVTable {
218            next: self.next.unwrap(),
219            next_back: self.next_back.unwrap(),
220            dealloc: self.dealloc.unwrap(),
221        }
222    }
223}
224
225/// Virtual table for a Map<K, V>
226#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
227#[repr(C)]
228pub struct MapVTable {
229    /// cf. [`MapInitInPlaceWithCapacityFn`]
230    pub init_in_place_with_capacity_fn: MapInitInPlaceWithCapacityFn,
231
232    /// cf. [`MapInsertFn`]
233    pub insert_fn: MapInsertFn,
234
235    /// cf. [`MapLenFn`]
236    pub len_fn: MapLenFn,
237
238    /// cf. [`MapContainsKeyFn`]
239    pub contains_key_fn: MapContainsKeyFn,
240
241    /// cf. [`MapGetValuePtrFn`]
242    pub get_value_ptr_fn: MapGetValuePtrFn,
243
244    /// cf. [`MapIterFn`]
245    pub iter_fn: MapIterFn,
246
247    /// Virtual table for map iterator operations
248    pub iter_vtable: MapIterVTable,
249}
250
251impl MapVTable {
252    /// Returns a builder for MapVTable
253    pub const fn builder() -> MapVTableBuilder {
254        MapVTableBuilder::new()
255    }
256}
257
258/// Builds a [`MapVTable`]
259pub struct MapVTableBuilder {
260    init_in_place_with_capacity_fn: Option<MapInitInPlaceWithCapacityFn>,
261    insert_fn: Option<MapInsertFn>,
262    len_fn: Option<MapLenFn>,
263    contains_key_fn: Option<MapContainsKeyFn>,
264    get_value_ptr_fn: Option<MapGetValuePtrFn>,
265    iter_fn: Option<MapIterFn>,
266    iter_vtable: Option<MapIterVTable>,
267}
268
269impl MapVTableBuilder {
270    /// Creates a new [`MapVTableBuilder`] with all fields set to `None`.
271    #[allow(clippy::new_without_default)]
272    pub const fn new() -> Self {
273        Self {
274            init_in_place_with_capacity_fn: None,
275            insert_fn: None,
276            len_fn: None,
277            contains_key_fn: None,
278            get_value_ptr_fn: None,
279            iter_fn: None,
280            iter_vtable: None,
281        }
282    }
283
284    /// Sets the init_in_place_with_capacity_fn field
285    pub const fn init_in_place_with_capacity(mut self, f: MapInitInPlaceWithCapacityFn) -> Self {
286        self.init_in_place_with_capacity_fn = Some(f);
287        self
288    }
289
290    /// Sets the insert_fn field
291    pub const fn insert(mut self, f: MapInsertFn) -> Self {
292        self.insert_fn = Some(f);
293        self
294    }
295
296    /// Sets the len_fn field
297    pub const fn len(mut self, f: MapLenFn) -> Self {
298        self.len_fn = Some(f);
299        self
300    }
301
302    /// Sets the contains_key_fn field
303    pub const fn contains_key(mut self, f: MapContainsKeyFn) -> Self {
304        self.contains_key_fn = Some(f);
305        self
306    }
307
308    /// Sets the get_value_ptr_fn field
309    pub const fn get_value_ptr(mut self, f: MapGetValuePtrFn) -> Self {
310        self.get_value_ptr_fn = Some(f);
311        self
312    }
313
314    /// Sets the iter_fn field
315    pub const fn iter(mut self, f: MapIterFn) -> Self {
316        self.iter_fn = Some(f);
317        self
318    }
319
320    /// Sets the iter_vtable field
321    pub const fn iter_vtable(mut self, vtable: MapIterVTable) -> Self {
322        self.iter_vtable = Some(vtable);
323        self
324    }
325
326    /// Builds the [`MapVTable`] from the current state of the builder.
327    ///
328    /// # Panics
329    ///
330    /// This method will panic if any of the required fields are `None`.
331    pub const fn build(self) -> MapVTable {
332        MapVTable {
333            init_in_place_with_capacity_fn: self.init_in_place_with_capacity_fn.unwrap(),
334            insert_fn: self.insert_fn.unwrap(),
335            len_fn: self.len_fn.unwrap(),
336            contains_key_fn: self.contains_key_fn.unwrap(),
337            get_value_ptr_fn: self.get_value_ptr_fn.unwrap(),
338            iter_fn: self.iter_fn.unwrap(),
339            iter_vtable: self.iter_vtable.unwrap(),
340        }
341    }
342}