iddqd/
errors.rs

1//! Error types for this crate.
2//!
3//! These types are shared across all map implementations in this crate.
4
5use alloc::vec::Vec;
6use core::fmt;
7
8/// An item conflicts with existing items.
9#[derive(Debug)]
10pub struct DuplicateItem<T, D = T> {
11    new: T,
12    duplicates: Vec<D>,
13}
14
15impl<T, D> DuplicateItem<T, D> {
16    /// Creates a new `DuplicateItem` error.
17    #[doc(hidden)]
18    pub fn __internal_new(new: T, duplicates: Vec<D>) -> Self {
19        DuplicateItem { new, duplicates }
20    }
21
22    /// Returns the new item that was attempted to be inserted.
23    #[inline]
24    pub fn new_item(&self) -> &T {
25        &self.new
26    }
27
28    /// Returns the list of items that conflict with the new item.
29    #[inline]
30    pub fn duplicates(&self) -> &[D] {
31        &self.duplicates
32    }
33
34    /// Converts self into its constituent parts.
35    pub fn into_parts(self) -> (T, Vec<D>) {
36        (self.new, self.duplicates)
37    }
38}
39
40impl<T: Clone> DuplicateItem<T, &T> {
41    /// Converts self to an owned `DuplicateItem` by cloning the list of
42    /// duplicates.
43    ///
44    /// If `T` is `'static`, the owned form is suitable for conversion to
45    /// `Box<dyn std::error::Error>`, `anyhow::Error`, and so on.
46    pub fn into_owned(self) -> DuplicateItem<T> {
47        DuplicateItem {
48            new: self.new,
49            duplicates: self.duplicates.into_iter().cloned().collect(),
50        }
51    }
52}
53
54impl<T: fmt::Debug, D: fmt::Debug> fmt::Display for DuplicateItem<T, D> {
55    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56        write!(
57            f,
58            "new item: {:?} conflicts with existing: {:?}",
59            self.new, self.duplicates
60        )
61    }
62}
63
64impl<T: fmt::Debug, D: fmt::Debug> core::error::Error for DuplicateItem<T, D> {}
65
66/// The error type for `try_reserve` methods.
67///
68/// This wraps the underlying allocation error from the hash table implementation.
69#[derive(Clone, PartialEq, Eq, Debug)]
70pub struct TryReserveError {
71    kind: TryReserveErrorKind,
72}
73
74#[derive(Clone, PartialEq, Eq, Debug)]
75enum TryReserveErrorKind {
76    /// Error due to the computed capacity exceeding the collection's maximum
77    /// (usually `isize::MAX` bytes).
78    CapacityOverflow,
79
80    /// The memory allocator returned an error
81    AllocError {
82        /// The layout of the allocation request that failed
83        layout: core::alloc::Layout,
84    },
85}
86
87impl TryReserveError {
88    /// Converts from a hashbrown `TryReserveError`.
89    pub(crate) fn from_hashbrown(error: hashbrown::TryReserveError) -> Self {
90        let kind = match error {
91            hashbrown::TryReserveError::CapacityOverflow => {
92                TryReserveErrorKind::CapacityOverflow
93            }
94            hashbrown::TryReserveError::AllocError { layout } => {
95                TryReserveErrorKind::AllocError { layout }
96            }
97        };
98        Self { kind }
99    }
100}
101
102impl fmt::Display for TryReserveError {
103    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104        match &self.kind {
105            TryReserveErrorKind::CapacityOverflow => {
106                write!(f, "capacity overflow")
107            }
108            TryReserveErrorKind::AllocError { .. } => {
109                write!(f, "memory allocation failed")
110            }
111        }
112    }
113}
114
115impl core::error::Error for TryReserveError {}