Skip to main content

rkyv/
result.rs

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