1use std::{
2 fmt,
3 hash::Hash,
4 iter::{FilterMap, FusedIterator},
5 marker::PhantomData,
6};
7
8use crate::{sys, AllocationError, Set};
9
10pub struct Map<'a, K = u32, V = u32>(InnerMap, PhantomData<(&'a (), (K, V))>);
14
15impl<K, V> Map<'static, K, V> {
16 #[doc(alias = "hb_map_create")]
18 pub fn new() -> Result<Self, AllocationError> {
19 let map = unsafe { sys::hb_map_create() };
20 if map.is_null() {
21 return Err(AllocationError);
22 }
23 Ok(Self(InnerMap(map), PhantomData))
24 }
25}
26
27impl<'a, K, V> Map<'a, K, V> {
28 #[doc(alias = "hb_map_is_empty")]
30 pub fn is_empty(&self) -> bool {
31 (unsafe { sys::hb_map_is_empty(self.as_raw()) }) != 0
32 }
33
34 #[doc(alias = "hb_map_get_population")]
36 pub fn len(&self) -> usize {
37 (unsafe { sys::hb_map_get_population(self.as_raw()) }) as usize
38 }
39
40 #[doc(alias = "hb_map_clear")]
42 pub fn clear(&mut self) {
43 unsafe { sys::hb_map_clear(self.as_raw()) }
44 }
45
46 #[doc(alias = "hb_map_copy")]
48 pub fn clone_static(&self) -> Map<'static, K, V> {
49 Map(
50 InnerMap(unsafe { sys::hb_map_copy(self.as_raw()) }),
51 PhantomData,
52 )
53 }
54
55 pub fn update(&mut self, other: &Self) {
57 unsafe { sys::hb_map_update(self.as_raw(), other.as_raw()) }
58 }
59
60 #[doc(alias = "hb_map_keys")]
62 pub fn keys(&self) -> Result<Set<'static, K>, AllocationError> {
63 let set = Set::new()?;
64 unsafe { sys::hb_map_keys(self.as_raw(), set.as_raw()) };
65 Ok(set)
66 }
67
68 #[doc(alias = "hb_map_values")]
70 pub fn values(&self) -> Result<Set<'static, V>, AllocationError> {
71 let set = Set::new()?;
72 unsafe { sys::hb_map_values(self.as_raw(), set.as_raw()) };
73 Ok(set)
74 }
75}
76
77impl<'a, K, V> Map<'a, K, V>
78where
79 K: Into<u32>,
80 V: Into<u32>,
81{
82 #[doc(alias = "hb_map_has")]
84 pub fn contains(&self, key: K) -> bool {
85 (unsafe { sys::hb_map_has(self.as_raw(), key.into()) }) != 0
86 }
87
88 #[doc(alias = "hb_map_del")]
90 pub fn remove(&mut self, key: K) {
91 unsafe { sys::hb_map_del(self.as_raw(), key.into()) }
92 }
93
94 #[doc(alias = "hb_map_set")]
96 pub fn insert(&mut self, key: K, value: V) {
97 let key = key.into();
98 let value = value.into();
99 unsafe { sys::hb_map_set(self.as_raw(), key, value) }
100 }
101}
102
103impl<'a, K, V> Map<'a, K, V>
104where
105 K: Into<u32>,
106 V: TryFrom<u32>,
107{
108 #[doc(alias = "hb_map_get")]
110 pub fn get(&self, key: K) -> Option<V> {
111 let key = key.into();
112 if (unsafe { sys::hb_map_has(self.as_raw(), key) }) != 0 {
113 V::try_from(unsafe { sys::hb_map_get(self.as_raw(), key) }).ok()
114 } else {
115 None
116 }
117 }
118}
119
120impl<'a, K, V> Map<'a, K, V>
121where
122 K: TryFrom<u32>,
123 V: TryFrom<u32>,
124{
125 #[doc(alias = "hb_map_next")]
127 pub fn iter(&self) -> MapIter<'_, 'a, K, V> {
128 MapIter(
129 MapIterImpl::new(self)
130 .filter_map(|(k, v)| Some((k.try_into().ok()?, v.try_into().ok()?))),
131 )
132 }
133}
134
135impl<'a, K, V> Map<'a, K, V> {
136 pub fn into_raw(self) -> *mut sys::hb_map_t {
141 let ptr = self.0 .0;
142 std::mem::forget(self);
143 ptr
144 }
145
146 pub fn as_raw(&self) -> *mut sys::hb_map_t {
150 self.0 .0
151 }
152
153 pub unsafe fn from_raw(map: *mut sys::hb_map_t) -> Self {
159 Self(InnerMap(map), PhantomData)
160 }
161}
162
163impl<'a, K, V> Hash for Map<'a, K, V> {
164 #[doc(alias = "hb_map_hash")]
165 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
166 unsafe { sys::hb_map_hash(self.as_raw()) }.hash(state);
167 }
168}
169
170impl<'a, K, V> PartialEq for Map<'a, K, V> {
171 #[doc(alias = "hb_map_is_equal")]
172 fn eq(&self, other: &Self) -> bool {
173 (unsafe { sys::hb_map_is_equal(self.as_raw(), other.as_raw()) }) != 0
174 }
175}
176
177impl<'a, K, V> Eq for Map<'a, K, V>
178where
179 K: Eq,
180 V: Eq,
181{
182}
183
184impl<'a, K, V> Clone for Map<'a, K, V> {
185 fn clone(&self) -> Self {
186 self.clone_static()
187 }
188}
189
190impl<'a, K, V> fmt::Debug for Map<'a, K, V>
191where
192 K: TryFrom<u32> + fmt::Debug,
193 V: TryFrom<u32> + fmt::Debug,
194{
195 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196 f.debug_map().entries(self).finish()
197 }
198}
199
200impl<'a, K, V> FromIterator<(K, V)> for Map<'a, K, V>
201where
202 K: Into<u32>,
203 V: Into<u32>,
204{
205 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
206 let mut map = Map::new().unwrap();
207 for (key, value) in iter {
208 map.insert(key, value);
209 }
210 map
211 }
212}
213
214impl<'m, 'a, K, V> IntoIterator for &'m Map<'a, K, V>
215where
216 K: TryFrom<u32>,
217 V: TryFrom<u32>,
218{
219 type Item = (K, V);
220 type IntoIter = MapIter<'m, 'a, K, V>;
221
222 fn into_iter(self) -> Self::IntoIter {
223 self.iter()
224 }
225}
226
227pub struct MapIter<'m, 'a, K, V>(MapIterFilter<'m, 'a, K, V>);
231type MapIterFilter<'m, 'a, K, V> =
232 FilterMap<MapIterImpl<'m, 'a, K, V>, fn((u32, u32)) -> Option<(K, V)>>;
233
234impl<'m, 'a, K, V> Iterator for MapIter<'m, 'a, K, V>
235where
236 K: TryFrom<u32>,
237 V: TryFrom<u32>,
238{
239 type Item = (K, V);
240
241 fn next(&mut self) -> Option<Self::Item> {
242 self.0.next()
243 }
244}
245
246impl<'m, 'a, K, V> FusedIterator for MapIter<'m, 'a, K, V>
247where
248 K: TryFrom<u32>,
249 V: TryFrom<u32>,
250{
251}
252
253struct MapIterImpl<'m, 'a, K, V>(&'m Map<'a, K, V>, i32);
255
256impl<'m, 'a, K, V> MapIterImpl<'m, 'a, K, V> {
257 fn new(map: &'m Map<'a, K, V>) -> Self {
258 Self(map, -1)
259 }
260}
261
262impl<'m, 'a, K, V> Iterator for MapIterImpl<'m, 'a, K, V> {
263 type Item = (u32, u32);
264
265 fn next(&mut self) -> Option<Self::Item> {
266 let mut key = 0;
267 let mut value = 0;
268 let prev_state = self.1;
269 let has_next = unsafe {
270 sys::hb_map_next(
271 self.0.as_raw(),
272 &mut self.1 as *mut i32,
273 &mut key as *mut u32,
274 &mut value as *mut u32,
275 )
276 } != 0;
277 if has_next {
278 Some((key, value))
279 } else {
280 self.1 = prev_state; None
282 }
283 }
284}
285
286struct InnerMap(*mut sys::hb_map_t);
290
291impl Drop for InnerMap {
292 #[doc(alias = "hb_map_destroy")]
293 fn drop(&mut self) {
294 unsafe { sys::hb_map_destroy(self.0) }
295 }
296}
297
298#[cfg(test)]
299mod tests {
300 use std::collections::BTreeSet;
301
302 use super::*;
303
304 #[test]
305 fn is_empty_works() {
306 let mut map = Map::<u32, u32>::new().unwrap();
307 assert!(map.is_empty());
308 map.insert(0, 0);
309 assert!(!map.is_empty());
310 map.insert(0, 10);
311 assert!(!map.is_empty());
312 map.remove(0);
313 assert!(map.is_empty());
314 }
315
316 #[test]
317 fn len_works() {
318 let mut map = Map::<u32, u32>::new().unwrap();
319 assert_eq!(map.len(), 0);
320 map.insert(0, 0);
321 assert_eq!(map.len(), 1);
322 map.insert(0, 10);
323 assert_eq!(map.len(), 1);
324 map.insert(1, 10);
325 assert_eq!(map.len(), 2);
326 map.remove(0);
327 assert_eq!(map.len(), 1);
328 map.remove(0);
329 assert_eq!(map.len(), 1);
330 map.remove(1);
331 assert_eq!(map.len(), 0);
332 }
333
334 #[test]
335 fn clear_works() {
336 let mut map = Map::<u32, u32>::from_iter([(0, 1), (0, 2), (1, 3)]);
337 assert_eq!(map.len(), 2);
338 map.clear();
339 assert!(map.is_empty());
340 assert_eq!(map.len(), 0);
341 }
342
343 #[test]
344 fn clone_does_not_change_original() {
345 let mut a = Map::<u32, u32>::from_iter([(0, 1), (1, 2), (10, 11)]);
346 let mut b = a.clone();
347 assert_eq!(a, b);
348 assert_eq!(b.len(), 3);
349 a.insert(20, 21);
350 assert_eq!(a.len(), 4);
351 assert_eq!(b.len(), 3);
352 b.remove(0);
353 assert_eq!(a.len(), 4);
354 assert_eq!(b.len(), 2);
355 }
356
357 #[test]
358 fn update_replaces_keys() {
359 let mut a = Map::<u32, u32>::from_iter([(0, 0), (1, 0), (10, 0)]);
360 let b = Map::<u32, u32>::from_iter([(1, 1), (5, 1), (11, 1)]);
361 a.update(&b);
362 assert_eq!(a.len(), 5);
363 assert_eq!(a.get(0).unwrap(), 0);
364 assert_eq!(a.get(1).unwrap(), 1);
365 assert_eq!(a.get(5).unwrap(), 1);
366 assert_eq!(a.get(10).unwrap(), 0);
367 assert_eq!(a.get(11).unwrap(), 1);
368 }
369
370 #[test]
371 fn keys_works() {
372 assert_eq!(
373 Map::<u32, u32>::from_iter([]).keys().unwrap(),
374 Set::from_iter([])
375 );
376 assert_eq!(
377 Map::<u32, u32>::from_iter([(0, 100), (1, 101), (10, 110)])
378 .keys()
379 .unwrap(),
380 Set::from_iter([0, 1, 10])
381 );
382 }
383
384 #[test]
385 fn values_works() {
386 assert_eq!(
387 Map::<u32, u32>::from_iter([]).values().unwrap(),
388 Set::from_iter([])
389 );
390 assert_eq!(
391 Map::<u32, u32>::from_iter([(0, 100), (1, 101), (10, 110)])
392 .values()
393 .unwrap(),
394 Set::from_iter([100, 101, 110])
395 );
396 }
397
398 #[test]
399 fn contains_works() {
400 let mut map = Map::<u32, u32>::new().unwrap();
401 assert!(!map.contains(0));
402 map.insert(0, 0);
403 assert!(map.contains(0));
404 map.insert(0, 10);
405 assert!(map.contains(0));
406 assert!(!map.contains(1));
407 map.insert(1, 10);
408 assert!(map.contains(0));
409 assert!(map.contains(1));
410 map.remove(0);
411 assert!(!map.contains(0));
412 assert!(map.contains(1));
413 map.remove(0);
414 assert!(!map.contains(0));
415 assert!(map.contains(1));
416 map.remove(1);
417 assert!(!map.contains(0));
418 assert!(!map.contains(1));
419 }
420
421 #[track_caller]
422 fn assert_set_is_correct<T: Ord + fmt::Debug>(
423 left: impl IntoIterator<Item = T>,
424 right: impl IntoIterator<Item = T>,
425 ) {
426 let left: BTreeSet<T> = BTreeSet::from_iter(left);
427 let right: BTreeSet<T> = BTreeSet::from_iter(right);
428 assert_eq!(left, right);
429 }
430
431 #[test]
432 #[should_panic]
433 fn assert_set_is_correct_detects_differences() {
434 assert_set_is_correct([1, 2], [1, 2, 3]);
435 }
436
437 #[test]
438 fn iter_works() {
439 let mut map = Map::<u32, u32>::from_iter([(0, 100), (4, 104)]);
440 assert_set_is_correct(map.iter(), [(0, 100), (4, 104)]);
441 map.insert(u32::MAX, u32::MAX);
442 assert_set_is_correct(map.iter(), [(0, 100), (4, 104), (u32::MAX, u32::MAX)]);
443 }
444
445 #[test]
446 fn iter_is_fused() {
447 let map = Map::<u32, u32>::from_iter([(0, 100), (4, 104)]);
448 let mut iter = map.iter();
449 assert!(iter.next().is_some());
450 assert!(iter.next().is_some());
451 assert!(iter.next().is_none());
452 assert!(iter.next().is_none());
453 assert!(iter.next().is_none());
454 assert!(iter.next().is_none());
455 assert!(iter.next().is_none());
456 }
457
458 #[test]
459 fn iter_of_invalid_codepoints_works() {
460 let mut map = Map::<u32, u32>::new().unwrap();
461 map.insert(0xD7FF, 10);
463 map.insert(0xE000, 10);
464 map.insert(20, 0xD7FF);
465 map.insert(21, 0xE000);
466
467 map.insert(0xD800, 3);
469 map.insert(0xD912, 4);
470 map.insert(0xDFFF, 5);
471
472 map.insert(23, 0xD800);
474 map.insert(24, 0xD912);
475 map.insert(25, 0xDFFF);
476
477 let char_to_u32_map = unsafe { Map::<char, u32>::from_raw(map.clone().into_raw()) };
478 assert_set_is_correct(
479 &char_to_u32_map,
480 [
481 ('\u{D7FF}', 10),
482 ('\u{E000}', 10),
483 ('\u{14}', 0xD7FF),
484 ('\u{15}', 0xE000),
485 ('\u{17}', 0xD800),
486 ('\u{18}', 0xD912),
487 ('\u{19}', 0xDFFF),
488 ],
489 );
490
491 let u32_to_char_map = unsafe { Map::<u32, char>::from_raw(map.clone().into_raw()) };
492 assert_set_is_correct(
493 &u32_to_char_map,
494 [
495 (0xD7FF, '\u{0a}'),
496 (0xE000, '\u{0a}'),
497 (20, '\u{D7FF}'),
498 (21, '\u{E000}'),
499 (0xD800, '\u{3}'),
500 (0xD912, '\u{4}'),
501 (0xDFFF, '\u{5}'),
502 ],
503 );
504
505 let char_to_char_map = unsafe { Map::<char, char>::from_raw(map.clone().into_raw()) };
506 assert_set_is_correct(
507 &char_to_char_map,
508 [
509 ('\u{D7FF}', '\u{0a}'),
510 ('\u{E000}', '\u{0a}'),
511 ('\u{14}', '\u{D7FF}'),
512 ('\u{15}', '\u{E000}'),
513 ],
514 );
515 }
516
517 #[test]
518 fn value_can_be_u32_max() {
519 let mut map = Map::<u32, u32>::new().unwrap();
520 map.insert(0, u32::MAX - 1);
521 map.insert(1, u32::MAX);
522 assert_eq!(map.len(), 2);
523 assert_eq!(map.get(0).unwrap(), u32::MAX - 1);
524 assert_eq!(map.get(1).unwrap(), u32::MAX);
525 }
526
527 #[test]
528 fn key_can_be_u32_max() {
529 let mut map = Map::<u32, u32>::new().unwrap();
530 map.insert(u32::MAX - 1, 10);
531 map.insert(u32::MAX, 20);
532 assert_eq!(map.len(), 2);
533 assert_eq!(map.get(u32::MAX - 1).unwrap(), 10);
534 assert_eq!(map.get(u32::MAX).unwrap(), 20);
535 }
536}