rkyv/
result.rs

1//! An archived version of `Result`.
2
3use core::{
4    cmp::{Ord, Ordering, PartialOrd},
5    hash, mem,
6    ops::{Deref, DerefMut},
7};
8
9/// An archived [`Result`] that represents either success ([`Ok`](ArchivedResult::Ok)) or failure
10/// ([`Err`](ArchivedResult::Err)).
11#[derive(Debug)]
12#[cfg_attr(feature = "validation", derive(bytecheck::CheckBytes))]
13#[repr(u8)]
14pub enum ArchivedResult<T, E> {
15    /// Contains the success value
16    Ok(T),
17    /// Contains the error value
18    Err(E),
19}
20
21impl<T, E> ArchivedResult<T, E> {
22    /// Converts from `ArchivedResult<T, E>` to `Option<T>`.
23    pub fn ok(self) -> Option<T> {
24        match self {
25            ArchivedResult::Ok(value) => Some(value),
26            ArchivedResult::Err(_) => None,
27        }
28    }
29    /// Returns the contained [`Ok`](ArchivedResult::Ok) value, consuming the `self` value.
30    pub fn unwrap(self) -> T {
31        match self {
32            ArchivedResult::Ok(value) => value,
33            ArchivedResult::Err(_) => panic!("called `ArchivedResult::unwrap()` on an `Err` value"),
34        }
35    }
36    /// Returns the contained `Ok` value or computes it from a closure.
37    pub fn unwrap_or_else<F>(self, op: F) -> T
38    where
39        F: FnOnce(E) -> T,
40    {
41        match self {
42            ArchivedResult::Ok(t) => t,
43            ArchivedResult::Err(e) => op(e),
44        }
45    }
46    /// Returns `true` if the result is [`Ok`](ArchivedResult::Ok).
47    #[inline]
48    pub const fn is_ok(&self) -> bool {
49        matches!(self, ArchivedResult::Ok(_))
50    }
51
52    /// Returns `true` if the result is [`Err`](ArchivedResult::Err).
53    #[inline]
54    pub const fn is_err(&self) -> bool {
55        matches!(self, ArchivedResult::Err(_))
56    }
57
58    /// Returns a `Result` containing the success and error values of this `ArchivedResult`.
59    #[inline]
60    pub fn as_ref(&self) -> Result<&T, &E> {
61        match self {
62            ArchivedResult::Ok(value) => Ok(value),
63            ArchivedResult::Err(err) => Err(err),
64        }
65    }
66
67    /// Converts from `&mut ArchivedResult<T, E>` to `Result<&mut T, &mut E>`.
68    #[inline]
69    pub fn as_mut(&mut self) -> Result<&mut T, &mut E> {
70        match self {
71            ArchivedResult::Ok(value) => Ok(value),
72            ArchivedResult::Err(err) => Err(err),
73        }
74    }
75
76    /// Returns an iterator over the possibly contained value.
77    ///
78    /// The iterator yields one value if the result is `ArchivedResult::Ok`, otherwise none.
79    #[inline]
80    pub fn iter(&self) -> Iter<'_, T> {
81        Iter {
82            inner: self.as_ref().ok(),
83        }
84    }
85
86    /// Returns a mutable iterator over the possibly contained value.
87    ///
88    /// The iterator yields one value if the result is `ArchivedResult::Ok`, otherwise none.
89    #[inline]
90    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
91        IterMut {
92            inner: self.as_mut().ok(),
93        }
94    }
95}
96
97impl<T: Deref, E> ArchivedResult<T, E> {
98    /// Converts from `&ArchivedResult<T, E>` to `Result<&<T as Deref>::Target, &E>`.
99    ///
100    /// Coerces the `Ok` variant of the original `ArchivedResult` via `Deref` and returns the new
101    /// `Result`.
102    #[inline]
103    pub fn as_deref(&self) -> Result<&<T as Deref>::Target, &E> {
104        match self {
105            ArchivedResult::Ok(value) => Ok(value.deref()),
106            ArchivedResult::Err(err) => Err(err),
107        }
108    }
109}
110
111impl<T: DerefMut, E> ArchivedResult<T, E> {
112    /// Converts from `&mut ArchivedResult<T, E>` to `Result<&mut <T as Deref>::Target, &mut E>`.
113    ///
114    /// Coerces the `Ok` variant of the original `ArchivedResult` via `DerefMut` and returns the new
115    /// `Result`.
116    #[inline]
117    pub fn as_deref_mut(&mut self) -> Result<&mut <T as Deref>::Target, &mut E> {
118        match self {
119            ArchivedResult::Ok(value) => Ok(value.deref_mut()),
120            ArchivedResult::Err(err) => Err(err),
121        }
122    }
123}
124
125/// An iterator over a reference to the `Ok` variant of an [`ArchivedResult`].
126///
127/// The iterator yields one value if the result is `Ok`, otherwise none.
128///
129/// Created by [`ArchivedResult::iter`].
130pub struct Iter<'a, T> {
131    inner: Option<&'a T>,
132}
133
134impl<'a, T> Iterator for Iter<'a, T> {
135    type Item = &'a T;
136
137    fn next(&mut self) -> Option<Self::Item> {
138        let mut result = None;
139        mem::swap(&mut self.inner, &mut result);
140        result
141    }
142}
143
144impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
145    fn next_back(&mut self) -> Option<Self::Item> {
146        self.next()
147    }
148}
149
150/// An iterator over a mutable reference to the `Ok` variant of an [`ArchivedResult`].
151///
152/// The iterator yields one value if the result is `Ok`, otherwise none.
153///
154/// Created by [`ArchivedResult::iter_mut`].
155pub struct IterMut<'a, T> {
156    inner: Option<&'a mut T>,
157}
158
159impl<'a, T> Iterator for IterMut<'a, T> {
160    type Item = &'a mut T;
161
162    fn next(&mut self) -> Option<Self::Item> {
163        let mut result = None;
164        mem::swap(&mut self.inner, &mut result);
165        result
166    }
167}
168
169impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
170    fn next_back(&mut self) -> Option<Self::Item> {
171        self.next()
172    }
173}
174
175impl<T: Eq, E: Eq> Eq for ArchivedResult<T, E> {}
176
177impl<T: hash::Hash, E: hash::Hash> hash::Hash for ArchivedResult<T, E> {
178    #[inline]
179    fn hash<H: hash::Hasher>(&self, state: &mut H) {
180        self.as_ref().hash(state)
181    }
182}
183
184impl<T: Ord, E: Ord> Ord for ArchivedResult<T, E> {
185    #[inline]
186    fn cmp(&self, other: &Self) -> Ordering {
187        self.as_ref().cmp(&other.as_ref())
188    }
189}
190
191impl<T: PartialEq, E: PartialEq> PartialEq for ArchivedResult<T, E> {
192    #[inline]
193    fn eq(&self, other: &Self) -> bool {
194        self.as_ref().eq(&other.as_ref())
195    }
196}
197
198impl<T: PartialOrd, E: PartialOrd> PartialOrd for ArchivedResult<T, E> {
199    #[inline]
200    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
201        self.as_ref().partial_cmp(&other.as_ref())
202    }
203}
204
205impl<T, U: PartialEq<T>, E, F: PartialEq<E>> PartialEq<Result<T, E>> for ArchivedResult<U, F> {
206    #[inline]
207    fn eq(&self, other: &Result<T, E>) -> bool {
208        match self {
209            ArchivedResult::Ok(self_value) => {
210                if let Ok(other_value) = other {
211                    self_value.eq(other_value)
212                } else {
213                    false
214                }
215            }
216            ArchivedResult::Err(self_err) => {
217                if let Err(other_err) = other {
218                    self_err.eq(other_err)
219                } else {
220                    false
221                }
222            }
223        }
224    }
225}
226
227impl<T: PartialEq<U>, U, E: PartialEq<F>, F> PartialEq<ArchivedResult<T, E>> for Result<U, F> {
228    #[inline]
229    fn eq(&self, other: &ArchivedResult<T, E>) -> bool {
230        other.eq(self)
231    }
232}