iddqd/id_ord_map/
trait_defs.rs

1//! Trait definitions for `IdOrdMap`.
2
3use alloc::{boxed::Box, rc::Rc, sync::Arc};
4
5/// An element stored in an [`IdOrdMap`].
6///
7/// This trait is used to define the key type for the map.
8///
9/// # Examples
10///
11/// ```
12/// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
13///
14/// // Define a struct with a key.
15/// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
16/// struct MyItem {
17///     id: String,
18///     value: u32,
19/// }
20///
21/// // Implement IdOrdItem for the struct.
22/// impl IdOrdItem for MyItem {
23///     // Keys can borrow from the item.
24///     type Key<'a> = &'a str;
25///
26///     fn key(&self) -> Self::Key<'_> {
27///         &self.id
28///     }
29///
30///     id_upcast!();
31/// }
32///
33/// // Create an IdOrdMap and insert items.
34/// let mut map = IdOrdMap::new();
35/// map.insert_unique(MyItem { id: "foo".to_string(), value: 42 }).unwrap();
36/// map.insert_unique(MyItem { id: "bar".to_string(), value: 20 }).unwrap();
37/// ```
38///
39/// [`IdOrdMap`]: crate::IdOrdMap
40pub trait IdOrdItem {
41    /// The key type.
42    type Key<'a>: Ord
43    where
44        Self: 'a;
45
46    /// Retrieves the key.
47    fn key(&self) -> Self::Key<'_>;
48
49    /// Upcasts the key to a shorter lifetime, in effect asserting that the
50    /// lifetime `'a` on [`IdOrdItem::Key`] is covariant.
51    ///
52    /// Typically implemented via the [`id_upcast`] macro.
53    ///
54    /// [`id_upcast`]: crate::id_upcast
55    fn upcast_key<'short, 'long: 'short>(
56        long: Self::Key<'long>,
57    ) -> Self::Key<'short>;
58}
59
60macro_rules! impl_for_ref {
61    ($type:ty) => {
62        impl<'b, T: 'b + ?Sized + IdOrdItem> IdOrdItem for $type {
63            type Key<'a>
64                = T::Key<'a>
65            where
66                Self: 'a;
67
68            fn key(&self) -> Self::Key<'_> {
69                (**self).key()
70            }
71
72            fn upcast_key<'short, 'long: 'short>(
73                long: Self::Key<'long>,
74            ) -> Self::Key<'short>
75            where
76                Self: 'long,
77            {
78                T::upcast_key(long)
79            }
80        }
81    };
82}
83
84impl_for_ref!(&'b T);
85impl_for_ref!(&'b mut T);
86
87macro_rules! impl_for_box {
88    ($type:ty) => {
89        impl<T: ?Sized + IdOrdItem> IdOrdItem for $type {
90            type Key<'a>
91                = T::Key<'a>
92            where
93                Self: 'a;
94
95            fn key(&self) -> Self::Key<'_> {
96                (**self).key()
97            }
98
99            fn upcast_key<'short, 'long: 'short>(
100                long: Self::Key<'long>,
101            ) -> Self::Key<'short> {
102                T::upcast_key(long)
103            }
104        }
105    };
106}
107
108impl_for_box!(Box<T>);
109impl_for_box!(Rc<T>);
110impl_for_box!(Arc<T>);