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