-
-
Notifications
You must be signed in to change notification settings - Fork 450
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revise rand_core::Error (alt #771) #800
Changes from 1 commit
6daae3e
a4e5f01
25650c4
b61e61b
f42abf8
959043d
ca1b7c4
4da7750
c5a5ab1
2d55947
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,13 +9,13 @@ | |
//! Error types | ||
|
||
use core::fmt; | ||
|
||
#[cfg(feature="std")] | ||
use std::error::Error as stdError; | ||
#[cfg(feature="std")] | ||
use std::io; | ||
#[cfg(not(feature="std"))] | ||
use core::num::NonZeroU32; | ||
|
||
|
||
// A randomly-chosen 24-bit prefix for our codes. | ||
#[cfg(not(feature="std"))] | ||
pub(crate) const CODE_PREFIX: u32 = 0x517e8100; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current |
||
|
||
/// Error type of random number generators | ||
/// | ||
|
@@ -30,7 +30,9 @@ pub struct Error { | |
/// The error message | ||
pub msg: &'static str, | ||
#[cfg(feature="std")] | ||
cause: Option<Box<stdError + Send + Sync>>, | ||
cause: Option<Box<std::error::Error + Send + Sync>>, | ||
#[cfg(not(feature="std"))] | ||
code: NonZeroU32, | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't this still have the issue that the error types are incompatible for different features, making the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, with enabled There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Functionally this is the case (and the |
||
|
||
impl Error { | ||
|
@@ -40,39 +42,45 @@ impl Error { | |
Error { msg, cause: None } | ||
} | ||
#[cfg(not(feature="std"))] { | ||
Error { msg } | ||
Error { msg, code: NonZeroU32::new(CODE_PREFIX).unwrap() } | ||
} | ||
} | ||
|
||
/// Create a new instance, with a message and a chained cause. | ||
/// | ||
/// Note: `stdError` is an alias for `std::error::Error`. | ||
/// | ||
/// If not targetting `std` (i.e. `no_std`), this function is replaced by | ||
/// another with the same prototype, except that there are no bounds on the | ||
/// type `E` (because both `Box` and `stdError` are unavailable), and the | ||
/// `cause` is ignored. | ||
/// | ||
/// This function is only available with the `std` feature. | ||
// NOTE: with specialisation we could support both. | ||
#[cfg(feature="std")] | ||
pub fn with_cause<E>(msg: &'static str, cause: E) -> Self | ||
where E: Into<Box<stdError + Send + Sync>> | ||
where E: Into<Box<std::error::Error + Send + Sync>> | ||
{ | ||
Error { msg, cause: Some(cause.into()) } | ||
} | ||
|
||
/// Create a new instance, with a message and a chained cause. | ||
/// | ||
/// In `no_std` mode the *cause* is ignored. | ||
/// Create a new instance, with a message and an error code. | ||
/// | ||
/// This function is only available without the `std` feature. | ||
#[cfg(not(feature="std"))] | ||
pub fn with_cause<E>(msg: &'static str, _cause: E) -> Self { | ||
Error { msg } | ||
pub fn with_code(msg: &'static str, code: NonZeroU32) -> Self { | ||
Error { msg, code } | ||
} | ||
|
||
/// Take the cause, if any. This allows the embedded cause to be extracted. | ||
/// This uses `Option::take`, leaving `self` with no cause. | ||
/// | ||
/// This function is only available with the `std` feature. | ||
#[cfg(feature="std")] | ||
pub fn take_cause(&mut self) -> Option<Box<stdError + Send + Sync>> { | ||
pub fn take_cause(&mut self) -> Option<Box<std::error::Error + Send + Sync>> { | ||
self.cause.take() | ||
} | ||
|
||
/// Retrieve the error code. | ||
/// | ||
/// This function is only available without the `std` feature. | ||
#[cfg(not(feature="std"))] | ||
pub fn code(&self) -> NonZeroU32 { | ||
self.code | ||
} | ||
} | ||
|
||
impl fmt::Display for Error { | ||
|
@@ -87,20 +95,33 @@ impl fmt::Display for Error { | |
} | ||
} | ||
|
||
#[cfg(feature="getrandom")] | ||
impl From<getrandom::Error> for Error { | ||
fn from(error: getrandom::Error) -> Self { | ||
let msg = "getrandom error"; | ||
#[cfg(feature="std")] { | ||
Error { msg, cause: Some(Box::new(error)) } | ||
} | ||
#[cfg(not(feature="std"))] { | ||
Error { msg, code: error.code() } | ||
} | ||
} | ||
} | ||
|
||
#[cfg(feature="std")] | ||
impl stdError for Error { | ||
impl std::error::Error for Error { | ||
fn description(&self) -> &str { | ||
self.msg | ||
} | ||
|
||
fn cause(&self) -> Option<&stdError> { | ||
self.cause.as_ref().map(|e| e.as_ref() as &stdError) | ||
fn cause(&self) -> Option<&std::error::Error> { | ||
self.cause.as_ref().map(|e| e.as_ref() as &std::error::Error) | ||
} | ||
} | ||
|
||
#[cfg(feature="std")] | ||
impl From<Error> for io::Error { | ||
impl From<Error> for std::io::Error { | ||
fn from(error: Error) -> Self { | ||
io::Error::new(io::ErrorKind::Other, error) | ||
std::io::Error::new(std::io::ErrorKind::Other, error) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this coupled to
getrandom
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean we should support
std
withoutgetrandom
? We could try, but (1)getrandom
supports (pretty-much) anystd
platform anyway and (2) I'm not sure Cargo allows us to implygetrandom/std
only when bothstd
andgetrandom
are enabled.