facet_core/types/
map.rs

1use crate::opaque::{Opaque, OpaqueConst, OpaqueUninit};
2
3/// Initialize a map in place with a given capacity
4///
5/// # Safety
6///
7/// The `map` parameter must point to uninitialized memory of sufficient size.
8/// The function must properly initialize the memory.
9pub type MapInitInPlaceWithCapacityFn =
10    unsafe fn(map: OpaqueUninit, capacity: usize) -> Result<Opaque, ()>;
11
12/// Insert a key-value pair into the map
13///
14/// # Safety
15///
16/// The `map` parameter must point to aligned, initialized memory of the correct type.
17/// `key` and `value` are moved out of (with [`core::ptr::read`]) — they should be deallocated
18/// afterwards but NOT dropped.
19pub type MapInsertFn =
20    for<'map, 'key, 'value> unsafe fn(map: Opaque<'map>, key: Opaque<'key>, value: Opaque<'value>);
21
22/// Get the number of entries in the map
23///
24/// # Safety
25///
26/// The `map` parameter must point to aligned, initialized memory of the correct type.
27pub type MapLenFn = for<'map> unsafe fn(map: OpaqueConst<'map>) -> usize;
28
29/// Check if the map contains a key
30///
31/// # Safety
32///
33/// The `map` parameter must point to aligned, initialized memory of the correct type.
34pub type MapContainsKeyFn =
35    for<'map, 'key> unsafe fn(map: OpaqueConst<'map>, key: OpaqueConst<'key>) -> bool;
36
37/// Get pointer to a value for a given key, returns None if not found
38///
39/// # Safety
40///
41/// The `map` parameter must point to aligned, initialized memory of the correct type.
42pub type MapGetValuePtrFn = for<'map, 'key> unsafe fn(
43    map: OpaqueConst<'map>,
44    key: OpaqueConst<'key>,
45) -> Option<OpaqueConst<'map>>;
46
47/// Get an iterator over the map
48///
49/// # Safety
50///
51/// The `map` parameter must point to aligned, initialized memory of the correct type.
52pub type MapIterFn = for<'map> unsafe fn(map: OpaqueConst<'map>) -> Opaque<'map>;
53
54/// Get the next key-value pair from the iterator
55///
56/// # Safety
57///
58/// The `iter` parameter must point to aligned, initialized memory of the correct type.
59pub type MapIterNextFn =
60    for<'iter> unsafe fn(iter: Opaque<'iter>) -> Option<(OpaqueConst<'iter>, OpaqueConst<'iter>)>;
61
62/// Deallocate the iterator
63///
64/// # Safety
65///
66/// The `iter` parameter must point to aligned, initialized memory of the correct type.
67pub type MapIterDeallocFn = for<'iter> unsafe fn(iter: Opaque<'iter>);
68
69/// VTable for an iterator over a map
70#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
71#[repr(C)]
72#[non_exhaustive]
73pub struct MapIterVTable {
74    /// cf. [`MapIterNextFn`]
75    pub next: MapIterNextFn,
76
77    /// cf. [`MapIterDeallocFn`]
78    pub dealloc: MapIterDeallocFn,
79}
80
81impl MapIterVTable {
82    /// Returns a builder for MapIterVTable
83    pub const fn builder() -> MapIterVTableBuilder {
84        MapIterVTableBuilder::new()
85    }
86}
87
88/// Builds a [`MapIterVTable`]
89pub struct MapIterVTableBuilder {
90    next: Option<MapIterNextFn>,
91    dealloc: Option<MapIterDeallocFn>,
92}
93
94impl MapIterVTableBuilder {
95    /// Creates a new [`MapIterVTableBuilder`] with all fields set to `None`.
96    #[allow(clippy::new_without_default)]
97    pub const fn new() -> Self {
98        Self {
99            next: None,
100            dealloc: None,
101        }
102    }
103
104    /// Sets the next field
105    pub const fn next(mut self, f: MapIterNextFn) -> Self {
106        self.next = Some(f);
107        self
108    }
109
110    /// Sets the dealloc field
111    pub const fn dealloc(mut self, f: MapIterDeallocFn) -> Self {
112        self.dealloc = Some(f);
113        self
114    }
115
116    /// Builds the [`MapIterVTable`] from the current state of the builder.
117    ///
118    /// # Panics
119    ///
120    /// This method will panic if any of the required fields are `None`.
121    pub const fn build(self) -> MapIterVTable {
122        MapIterVTable {
123            next: self.next.unwrap(),
124            dealloc: self.dealloc.unwrap(),
125        }
126    }
127}
128
129/// Virtual table for a Map<K, V>
130#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
131#[repr(C)]
132pub struct MapVTable {
133    /// cf. [`MapInitInPlaceWithCapacityFn`]
134    pub init_in_place_with_capacity_fn: MapInitInPlaceWithCapacityFn,
135
136    /// cf. [`MapInsertFn`]
137    pub insert_fn: MapInsertFn,
138
139    /// cf. [`MapLenFn`]
140    pub len_fn: MapLenFn,
141
142    /// cf. [`MapContainsKeyFn`]
143    pub contains_key_fn: MapContainsKeyFn,
144
145    /// cf. [`MapGetValuePtrFn`]
146    pub get_value_ptr_fn: MapGetValuePtrFn,
147
148    /// cf. [`MapIterFn`]
149    pub iter_fn: MapIterFn,
150
151    /// Virtual table for map iterator operations
152    pub iter_vtable: MapIterVTable,
153}
154
155impl MapVTable {
156    /// Returns a builder for MapVTable
157    pub const fn builder() -> MapVTableBuilder {
158        MapVTableBuilder::new()
159    }
160}
161
162/// Builds a [`MapVTable`]
163pub struct MapVTableBuilder {
164    init_in_place_with_capacity_fn: Option<MapInitInPlaceWithCapacityFn>,
165    insert_fn: Option<MapInsertFn>,
166    len_fn: Option<MapLenFn>,
167    contains_key_fn: Option<MapContainsKeyFn>,
168    get_value_ptr_fn: Option<MapGetValuePtrFn>,
169    iter_fn: Option<MapIterFn>,
170    iter_vtable: Option<MapIterVTable>,
171}
172
173impl MapVTableBuilder {
174    /// Creates a new [`MapVTableBuilder`] with all fields set to `None`.
175    #[allow(clippy::new_without_default)]
176    pub const fn new() -> Self {
177        Self {
178            init_in_place_with_capacity_fn: None,
179            insert_fn: None,
180            len_fn: None,
181            contains_key_fn: None,
182            get_value_ptr_fn: None,
183            iter_fn: None,
184            iter_vtable: None,
185        }
186    }
187
188    /// Sets the init_in_place_with_capacity_fn field
189    pub const fn init_in_place_with_capacity(mut self, f: MapInitInPlaceWithCapacityFn) -> Self {
190        self.init_in_place_with_capacity_fn = Some(f);
191        self
192    }
193
194    /// Sets the insert_fn field
195    pub const fn insert(mut self, f: MapInsertFn) -> Self {
196        self.insert_fn = Some(f);
197        self
198    }
199
200    /// Sets the len_fn field
201    pub const fn len(mut self, f: MapLenFn) -> Self {
202        self.len_fn = Some(f);
203        self
204    }
205
206    /// Sets the contains_key_fn field
207    pub const fn contains_key(mut self, f: MapContainsKeyFn) -> Self {
208        self.contains_key_fn = Some(f);
209        self
210    }
211
212    /// Sets the get_value_ptr_fn field
213    pub const fn get_value_ptr(mut self, f: MapGetValuePtrFn) -> Self {
214        self.get_value_ptr_fn = Some(f);
215        self
216    }
217
218    /// Sets the iter_fn field
219    pub const fn iter(mut self, f: MapIterFn) -> Self {
220        self.iter_fn = Some(f);
221        self
222    }
223
224    /// Sets the iter_vtable field
225    pub const fn iter_vtable(mut self, vtable: MapIterVTable) -> Self {
226        self.iter_vtable = Some(vtable);
227        self
228    }
229
230    /// Builds the [`MapVTable`] from the current state of the builder.
231    ///
232    /// # Panics
233    ///
234    /// This method will panic if any of the required fields are `None`.
235    pub const fn build(self) -> MapVTable {
236        MapVTable {
237            init_in_place_with_capacity_fn: self.init_in_place_with_capacity_fn.unwrap(),
238            insert_fn: self.insert_fn.unwrap(),
239            len_fn: self.len_fn.unwrap(),
240            contains_key_fn: self.contains_key_fn.unwrap(),
241            get_value_ptr_fn: self.get_value_ptr_fn.unwrap(),
242            iter_fn: self.iter_fn.unwrap(),
243            iter_vtable: self.iter_vtable.unwrap(),
244        }
245    }
246}