Skip to main content

rand_core/
unwrap_err.rs

1use crate::{Infallible, TryCryptoRng, TryRng};
2
3/// Wrapper around [`TryRng`] implementation which implements [`Rng`][crate::Rng]
4/// by panicking on potential errors.
5///
6/// # Examples
7///
8/// ```rust
9/// # use rand_core::{UnwrapErr, TryRng, Rng};
10/// fn with_try_rng<R: TryRng>(mut rng: R) {
11///     // rng does not impl Rng:
12///     let _ = rng.try_next_u32(); // okay
13///     // let _ = rng.next_u32(); // error
14///
15///     // An adapter borrowing rng:
16///     let _ = UnwrapErr(&mut rng).next_u32();
17///
18///     // An adapter moving rng:
19///     let mut rng = UnwrapErr(rng);
20///     let _ = rng.next_u32();
21/// }
22///
23/// fn call_with_unsized_try_rng<R: TryRng + ?Sized>(rng: &mut R) {
24///     // R is unsized, thus we must use &mut R:
25///     let mut rng = UnwrapErr(rng);
26///     let _ = rng.next_u32();
27/// }
28/// ```
29#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash)]
30pub struct UnwrapErr<R: TryRng>(pub R);
31
32impl<R: TryRng> TryRng for UnwrapErr<R> {
33    type Error = Infallible;
34
35    #[inline]
36    fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
37        self.0.try_next_u32().map_err(panic_msg)
38    }
39
40    #[inline]
41    fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
42        self.0.try_next_u64().map_err(panic_msg)
43    }
44
45    #[inline]
46    fn try_fill_bytes(&mut self, dst: &mut [u8]) -> Result<(), Self::Error> {
47        self.0.try_fill_bytes(dst).map_err(panic_msg)
48    }
49}
50
51fn panic_msg(err: impl core::error::Error) -> Infallible {
52    panic!("rand_core::UnwrapErr: failed to unwrap: {err}")
53}
54
55impl<R: TryCryptoRng> TryCryptoRng for UnwrapErr<R> {}
56
57impl<'r, R: TryRng + ?Sized> UnwrapErr<&'r mut R> {
58    /// Reborrow with a new lifetime
59    ///
60    /// Rust allows references like `&T` or `&mut T` to be "reborrowed" through
61    /// coercion: essentially, the pointer is copied under a new, shorter, lifetime.
62    /// Until rfcs#1403 lands, reborrows on user types require a method call.
63    #[inline(always)]
64    pub fn re<'b>(&'b mut self) -> UnwrapErr<&'b mut R>
65    where
66        'r: 'b,
67    {
68        UnwrapErr(self.0)
69    }
70}