facet_types/
map.rs

1use facet_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#[non_exhaustive]
72pub struct MapIterVTable {
73    /// cf. [`MapIterNextFn`]
74    pub next: MapIterNextFn,
75
76    /// cf. [`MapIterDeallocFn`]
77    pub dealloc: MapIterDeallocFn,
78}
79
80impl MapIterVTable {
81    /// Returns a builder for MapIterVTable
82    pub const fn builder() -> MapIterVTableBuilder {
83        MapIterVTableBuilder::new()
84    }
85}
86
87/// Builds a [`MapIterVTable`]
88pub struct MapIterVTableBuilder {
89    next: Option<MapIterNextFn>,
90    dealloc: Option<MapIterDeallocFn>,
91}
92
93impl MapIterVTableBuilder {
94    /// Creates a new [`MapIterVTableBuilder`] with all fields set to `None`.
95    #[allow(clippy::new_without_default)]
96    pub const fn new() -> Self {
97        Self {
98            next: None,
99            dealloc: None,
100        }
101    }
102
103    /// Sets the next field
104    pub const fn next(mut self, f: MapIterNextFn) -> Self {
105        self.next = Some(f);
106        self
107    }
108
109    /// Sets the dealloc field
110    pub const fn dealloc(mut self, f: MapIterDeallocFn) -> Self {
111        self.dealloc = Some(f);
112        self
113    }
114
115    /// Builds the [`MapIterVTable`] from the current state of the builder.
116    ///
117    /// # Panics
118    ///
119    /// This method will panic if any of the required fields are `None`.
120    pub const fn build(self) -> MapIterVTable {
121        MapIterVTable {
122            next: self.next.unwrap(),
123            dealloc: self.dealloc.unwrap(),
124        }
125    }
126}
127
128/// Virtual table for a Map<K, V>
129#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
130pub struct MapVTable {
131    /// cf. [`MapInitInPlaceWithCapacityFn`]
132    pub init_in_place_with_capacity_fn: MapInitInPlaceWithCapacityFn,
133
134    /// cf. [`MapInsertFn`]
135    pub insert_fn: MapInsertFn,
136
137    /// cf. [`MapLenFn`]
138    pub len_fn: MapLenFn,
139
140    /// cf. [`MapContainsKeyFn`]
141    pub contains_key_fn: MapContainsKeyFn,
142
143    /// cf. [`MapGetValuePtrFn`]
144    pub get_value_ptr_fn: MapGetValuePtrFn,
145
146    /// cf. [`MapIterFn`]
147    pub iter_fn: MapIterFn,
148
149    /// Virtual table for map iterator operations
150    pub iter_vtable: MapIterVTable,
151}
152
153impl MapVTable {
154    /// Returns a builder for MapVTable
155    pub const fn builder() -> MapVTableBuilder {
156        MapVTableBuilder::new()
157    }
158}
159
160/// Builds a [`MapVTable`]
161pub struct MapVTableBuilder {
162    init_in_place_with_capacity_fn: Option<MapInitInPlaceWithCapacityFn>,
163    insert_fn: Option<MapInsertFn>,
164    len_fn: Option<MapLenFn>,
165    contains_key_fn: Option<MapContainsKeyFn>,
166    get_value_ptr_fn: Option<MapGetValuePtrFn>,
167    iter_fn: Option<MapIterFn>,
168    iter_vtable: Option<MapIterVTable>,
169}
170
171impl MapVTableBuilder {
172    /// Creates a new [`MapVTableBuilder`] with all fields set to `None`.
173    #[allow(clippy::new_without_default)]
174    pub const fn new() -> Self {
175        Self {
176            init_in_place_with_capacity_fn: None,
177            insert_fn: None,
178            len_fn: None,
179            contains_key_fn: None,
180            get_value_ptr_fn: None,
181            iter_fn: None,
182            iter_vtable: None,
183        }
184    }
185
186    /// Sets the init_in_place_with_capacity_fn field
187    pub const fn init_in_place_with_capacity(mut self, f: MapInitInPlaceWithCapacityFn) -> Self {
188        self.init_in_place_with_capacity_fn = Some(f);
189        self
190    }
191
192    /// Sets the insert_fn field
193    pub const fn insert(mut self, f: MapInsertFn) -> Self {
194        self.insert_fn = Some(f);
195        self
196    }
197
198    /// Sets the len_fn field
199    pub const fn len(mut self, f: MapLenFn) -> Self {
200        self.len_fn = Some(f);
201        self
202    }
203
204    /// Sets the contains_key_fn field
205    pub const fn contains_key(mut self, f: MapContainsKeyFn) -> Self {
206        self.contains_key_fn = Some(f);
207        self
208    }
209
210    /// Sets the get_value_ptr_fn field
211    pub const fn get_value_ptr(mut self, f: MapGetValuePtrFn) -> Self {
212        self.get_value_ptr_fn = Some(f);
213        self
214    }
215
216    /// Sets the iter_fn field
217    pub const fn iter(mut self, f: MapIterFn) -> Self {
218        self.iter_fn = Some(f);
219        self
220    }
221
222    /// Sets the iter_vtable field
223    pub const fn iter_vtable(mut self, vtable: MapIterVTable) -> Self {
224        self.iter_vtable = Some(vtable);
225        self
226    }
227
228    /// Builds the [`MapVTable`] from the current state of the builder.
229    ///
230    /// # Panics
231    ///
232    /// This method will panic if any of the required fields are `None`.
233    pub const fn build(self) -> MapVTable {
234        MapVTable {
235            init_in_place_with_capacity_fn: self.init_in_place_with_capacity_fn.unwrap(),
236            insert_fn: self.insert_fn.unwrap(),
237            len_fn: self.len_fn.unwrap(),
238            contains_key_fn: self.contains_key_fn.unwrap(),
239            get_value_ptr_fn: self.get_value_ptr_fn.unwrap(),
240            iter_fn: self.iter_fn.unwrap(),
241            iter_vtable: self.iter_vtable.unwrap(),
242        }
243    }
244}