Skip to content

Commit d877ed5

Browse files
authored
Merge pull request #864 from dhardy/error
Update rand_core::Error in line with getrandom::Error
2 parents a4cd495 + 3b79aaa commit d877ed5

File tree

5 files changed

+82
-15
lines changed

5 files changed

+82
-15
lines changed

rand_core/CHANGELOG.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## [Unreleased]
8-
- `alloc` feature in `no_std` is available since Rust 1.36 (#856)
9-
10-
## [0.5.1] - 2019-09-02
11-
### Added
7+
## [0.5.1] - 2019-08-28
128
- `OsRng` added to `rand_core` (#863)
9+
- `Error::INTERNAL_START` and `Error::CUSTOM_START` constants (#864)
10+
- `Error::raw_os_error` method (#864)
11+
- `Debug` and `Display` formatting for `getrandom` error codes without `std` (#864)
12+
### Changed
13+
- `alloc` feature in `no_std` is available since Rust 1.36 (#856)
14+
- Added `#[inline]` to `Error` conversion methods (#864)
1315

1416
## [0.5.0] - 2019-06-06
1517
### Changed

rand_core/src/error.rs

+59-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use core::num::NonZeroU32;
1717
/// In order to be compatible with `std` and `no_std`, this type has two
1818
/// possible implementations: with `std` a boxed `Error` trait object is stored,
1919
/// while with `no_std` we merely store an error code.
20-
#[derive(Debug)]
2120
pub struct Error {
2221
#[cfg(feature="std")]
2322
inner: Box<dyn std::error::Error + Send + Sync + 'static>,
@@ -32,6 +31,7 @@ impl Error {
3231
///
3332
/// See also `From<NonZeroU32>`, which is available with and without `std`.
3433
#[cfg(feature="std")]
34+
#[inline]
3535
pub fn new<E>(err: E) -> Self
3636
where E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>
3737
{
@@ -43,6 +43,7 @@ impl Error {
4343
/// When configured with `std`, this is a trivial operation and never
4444
/// panics. Without `std`, this method is simply unavailable.
4545
#[cfg(feature="std")]
46+
#[inline]
4647
pub fn inner(&self) -> &(dyn std::error::Error + Send + Sync + 'static) {
4748
&*self.inner
4849
}
@@ -52,15 +53,45 @@ impl Error {
5253
/// When configured with `std`, this is a trivial operation and never
5354
/// panics. Without `std`, this method is simply unavailable.
5455
#[cfg(feature="std")]
56+
#[inline]
5557
pub fn take_inner(self) -> Box<dyn std::error::Error + Send + Sync + 'static> {
5658
self.inner
5759
}
5860

61+
/// Codes below this point represent OS Errors (i.e. positive i32 values).
62+
/// Codes at or above this point, but below [`Error::CUSTOM_START`] are
63+
/// reserved for use by the `rand` and `getrandom` crates.
64+
pub const INTERNAL_START: u32 = 1 << 31;
65+
66+
/// Codes at or above this point can be used by users to define their own
67+
/// custom errors.
68+
pub const CUSTOM_START: u32 = (1 << 31) + (1 << 30);
69+
70+
/// Extract the raw OS error code (if this error came from the OS)
71+
///
72+
/// This method is identical to `std::io::Error::raw_os_error()`, except
73+
/// that it works in `no_std` contexts. If this method returns `None`, the
74+
/// error value can still be formatted via the `Diplay` implementation.
75+
#[inline]
76+
pub fn raw_os_error(&self) -> Option<i32> {
77+
#[cfg(feature="std")] {
78+
if let Some(e) = self.inner.downcast_ref::<std::io::Error>() {
79+
return e.raw_os_error();
80+
}
81+
}
82+
match self.code() {
83+
Some(code) if u32::from(code) < Self::INTERNAL_START =>
84+
Some(u32::from(code) as i32),
85+
_ => None,
86+
}
87+
}
88+
5989
/// Retrieve the error code, if any.
6090
///
6191
/// If this `Error` was constructed via `From<NonZeroU32>`, then this method
6292
/// will return this `NonZeroU32` code (for `no_std` this is always the
6393
/// case). Otherwise, this method will return `None`.
94+
#[inline]
6495
pub fn code(&self) -> Option<NonZeroU32> {
6596
#[cfg(feature="std")] {
6697
self.inner.downcast_ref::<ErrorCode>().map(|c| c.0)
@@ -71,18 +102,36 @@ impl Error {
71102
}
72103
}
73104

105+
impl fmt::Debug for Error {
106+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107+
#[cfg(feature="std")] {
108+
write!(f, "Error {{ inner: {:?} }}", self.inner)
109+
}
110+
#[cfg(all(feature="getrandom", not(feature="std")))] {
111+
getrandom::Error::from(self.code).fmt(f)
112+
}
113+
#[cfg(not(feature="getrandom"))] {
114+
write!(f, "Error {{ code: {} }}", self.code)
115+
}
116+
}
117+
}
118+
74119
impl fmt::Display for Error {
75120
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76121
#[cfg(feature="std")] {
77122
write!(f, "{}", self.inner)
78123
}
79-
#[cfg(not(feature="std"))] {
124+
#[cfg(all(feature="getrandom", not(feature="std")))] {
125+
getrandom::Error::from(self.code).fmt(f)
126+
}
127+
#[cfg(not(feature="getrandom"))] {
80128
write!(f, "error code {}", self.code)
81129
}
82130
}
83131
}
84132

85133
impl From<NonZeroU32> for Error {
134+
#[inline]
86135
fn from(code: NonZeroU32) -> Self {
87136
#[cfg(feature="std")] {
88137
Error { inner: Box::new(ErrorCode(code)) }
@@ -95,6 +144,7 @@ impl From<NonZeroU32> for Error {
95144

96145
#[cfg(feature="getrandom")]
97146
impl From<getrandom::Error> for Error {
147+
#[inline]
98148
fn from(error: getrandom::Error) -> Self {
99149
#[cfg(feature="std")] {
100150
Error { inner: Box::new(error) }
@@ -107,15 +157,21 @@ impl From<getrandom::Error> for Error {
107157

108158
#[cfg(feature="std")]
109159
impl std::error::Error for Error {
160+
#[inline]
110161
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
111162
self.inner.source()
112163
}
113164
}
114165

115166
#[cfg(feature="std")]
116167
impl From<Error> for std::io::Error {
168+
#[inline]
117169
fn from(error: Error) -> Self {
118-
std::io::Error::new(std::io::ErrorKind::Other, error)
170+
if let Some(code) = error.raw_os_error() {
171+
std::io::Error::from_raw_os_error(code)
172+
} else {
173+
std::io::Error::new(std::io::ErrorKind::Other, error)
174+
}
119175
}
120176
}
121177

rand_jitter/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [0.2.1] - 2019-08-16
8+
### Changed
9+
- `TimerError` changed to `repr(u32)` (#864)
10+
- `TimerError` enum values all increased by `1<<30` to match new `rand_core::Error` range (#864)
11+
712
## [0.2.0] - 2019-06-06
813
- Bump `rand_core` version
914
- Support new `Error` type in `rand_core` 0.5

rand_jitter/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rand_jitter"
3-
version = "0.2.0"
3+
version = "0.2.1"
44
authors = ["The Rand Project Developers"]
55
license = "MIT OR Apache-2.0"
66
readme = "README.md"

rand_jitter/src/error.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,28 @@
1010
use rand_core::Error;
1111
use core::fmt;
1212

13+
/// Base code for all `JitterRng` errors
14+
const ERROR_BASE: u32 = 0xAE53_0400;
15+
1316
/// An error that can occur when [`JitterRng::test_timer`] fails.
1417
///
15-
/// All variants have a value of 0x6e530400 = 1850934272 plus a small
18+
/// All variants have a value of 0xAE530400 = 2924676096 plus a small
1619
/// increment (1 through 5).
1720
///
1821
/// [`JitterRng::test_timer`]: crate::JitterRng::test_timer
1922
#[derive(Debug, Clone, PartialEq, Eq)]
23+
#[repr(u32)]
2024
pub enum TimerError {
2125
/// No timer available.
22-
NoTimer = 0x6e530401,
26+
NoTimer = ERROR_BASE + 1,
2327
/// Timer too coarse to use as an entropy source.
24-
CoarseTimer = 0x6e530402,
28+
CoarseTimer = ERROR_BASE + 2,
2529
/// Timer is not monotonically increasing.
26-
NotMonotonic = 0x6e530403,
30+
NotMonotonic = ERROR_BASE + 3,
2731
/// Variations of deltas of time too small.
28-
TinyVariantions = 0x6e530404,
32+
TinyVariantions = ERROR_BASE + 4,
2933
/// Too many stuck results (indicating no added entropy).
30-
TooManyStuck = 0x6e530405,
34+
TooManyStuck = ERROR_BASE + 5,
3135
#[doc(hidden)]
3236
__Nonexhaustive,
3337
}

0 commit comments

Comments
 (0)