aboutsummaryrefslogtreecommitdiff
path: root/src/error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/error.rs')
-rw-r--r--src/error.rs95
1 files changed, 51 insertions, 44 deletions
diff --git a/src/error.rs b/src/error.rs
index 31ae24d..48abdc1 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -5,10 +5,9 @@
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use core::fmt;
-use core::num::NonZeroU32;
+use core::{fmt, num::NonZeroU32};
-/// A small and `no_std` compatible error type.
+/// A small and `no_std` compatible error type
///
/// The [`Error::raw_os_error()`] will indicate if the error is from the OS, and
/// if so, which error code the OS gave the application. If such an error is
@@ -16,16 +15,44 @@ use core::num::NonZeroU32;
///
/// Internally this type is a NonZeroU32, with certain values reserved for
/// certain purposes, see [`Error::INTERNAL_START`] and [`Error::CUSTOM_START`].
+///
+/// *If this crate's `"std"` Cargo feature is enabled*, then:
+/// - [`getrandom::Error`][Error] implements
+/// [`std::error::Error`](https://doc.rust-lang.org/std/error/trait.Error.html)
+/// - [`std::io::Error`](https://doc.rust-lang.org/std/io/struct.Error.html) implements
+/// [`From<getrandom::Error>`](https://doc.rust-lang.org/std/convert/trait.From.html).
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Error(NonZeroU32);
+const fn internal_error(n: u16) -> Error {
+ // SAFETY: code > 0 as INTERNAL_START > 0 and adding n won't overflow a u32.
+ let code = Error::INTERNAL_START + (n as u32);
+ Error(unsafe { NonZeroU32::new_unchecked(code) })
+}
+
impl Error {
- #[deprecated(since = "0.1.7")]
- /// Unknown error.
- pub const UNKNOWN: Error = UNSUPPORTED;
- #[deprecated(since = "0.1.7")]
- /// System entropy source is unavailable.
- pub const UNAVAILABLE: Error = UNSUPPORTED;
+ /// This target/platform is not supported by `getrandom`.
+ pub const UNSUPPORTED: Error = internal_error(0);
+ /// The platform-specific `errno` returned a non-positive value.
+ pub const ERRNO_NOT_POSITIVE: Error = internal_error(1);
+ /// Call to iOS [`SecRandomCopyBytes`](https://developer.apple.com/documentation/security/1399291-secrandomcopybytes) failed.
+ pub const IOS_SEC_RANDOM: Error = internal_error(3);
+ /// Call to Windows [`RtlGenRandom`](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom) failed.
+ pub const WINDOWS_RTL_GEN_RANDOM: Error = internal_error(4);
+ /// RDRAND instruction failed due to a hardware issue.
+ pub const FAILED_RDRAND: Error = internal_error(5);
+ /// RDRAND instruction unsupported on this target.
+ pub const NO_RDRAND: Error = internal_error(6);
+ /// The browser does not have support for `self.crypto`.
+ pub const WEB_CRYPTO: Error = internal_error(7);
+ /// The browser does not have support for `crypto.getRandomValues`.
+ pub const WEB_GET_RANDOM_VALUES: Error = internal_error(8);
+ /// On VxWorks, call to `randSecure` failed (random number generator is not yet initialized).
+ pub const VXWORKS_RAND_SECURE: Error = internal_error(11);
+ /// NodeJS does not have support for the `crypto` module.
+ pub const NODE_CRYPTO: Error = internal_error(12);
+ /// NodeJS does not have support for `crypto.randomFillSync`.
+ pub const NODE_RANDOM_FILL_SYNC: Error = internal_error(13);
/// Codes below this point represent OS Errors (i.e. positive i32 values).
/// Codes at or above this point, but below [`Error::CUSTOM_START`] are
@@ -38,9 +65,11 @@ impl Error {
/// Extract the raw OS error code (if this error came from the OS)
///
- /// This method is identical to `std::io::Error::raw_os_error()`, except
+ /// This method is identical to [`std::io::Error::raw_os_error()`][1], except
/// that it works in `no_std` contexts. If this method returns `None`, the
/// error value can still be formatted via the `Display` implementation.
+ ///
+ /// [1]: https://doc.rust-lang.org/std/io/struct.Error.html#method.raw_os_error
#[inline]
pub fn raw_os_error(self) -> Option<i32> {
if self.0.get() < Self::INTERNAL_START {
@@ -55,7 +84,7 @@ impl Error {
/// This code can either come from the underlying OS, or be a custom error.
/// Use [`Error::raw_os_error()`] to disambiguate.
#[inline]
- pub fn code(self) -> NonZeroU32 {
+ pub const fn code(self) -> NonZeroU32 {
self.0
}
}
@@ -125,41 +154,19 @@ impl From<NonZeroU32> for Error {
}
}
-// TODO: Convert to a function when min_version >= 1.33
-macro_rules! internal_error {
- ($n:expr) => {
- Error(unsafe { NonZeroU32::new_unchecked(Error::INTERNAL_START + $n as u16 as u32) })
- };
-}
-
-/// Internal Error constants
-pub(crate) const UNSUPPORTED: Error = internal_error!(0);
-pub(crate) const ERRNO_NOT_POSITIVE: Error = internal_error!(1);
-pub(crate) const UNKNOWN_IO_ERROR: Error = internal_error!(2);
-pub(crate) const SEC_RANDOM_FAILED: Error = internal_error!(3);
-pub(crate) const RTL_GEN_RANDOM_FAILED: Error = internal_error!(4);
-pub(crate) const FAILED_RDRAND: Error = internal_error!(5);
-pub(crate) const NO_RDRAND: Error = internal_error!(6);
-pub(crate) const BINDGEN_CRYPTO_UNDEF: Error = internal_error!(7);
-pub(crate) const BINDGEN_GRV_UNDEF: Error = internal_error!(8);
-pub(crate) const STDWEB_NO_RNG: Error = internal_error!(9);
-pub(crate) const STDWEB_RNG_FAILED: Error = internal_error!(10);
-pub(crate) const RAND_SECURE_FATAL: Error = internal_error!(11);
-
fn internal_desc(error: Error) -> Option<&'static str> {
match error {
- UNSUPPORTED => Some("getrandom: this target is not supported"),
- ERRNO_NOT_POSITIVE => Some("errno: did not return a positive value"),
- UNKNOWN_IO_ERROR => Some("Unknown std::io::Error"),
- SEC_RANDOM_FAILED => Some("SecRandomCopyBytes: call failed"),
- RTL_GEN_RANDOM_FAILED => Some("RtlGenRandom: call failed"),
- FAILED_RDRAND => Some("RDRAND: failed multiple times: CPU issue likely"),
- NO_RDRAND => Some("RDRAND: instruction not supported"),
- BINDGEN_CRYPTO_UNDEF => Some("wasm-bindgen: self.crypto is undefined"),
- BINDGEN_GRV_UNDEF => Some("wasm-bindgen: crypto.getRandomValues is undefined"),
- STDWEB_NO_RNG => Some("stdweb: no randomness source available"),
- STDWEB_RNG_FAILED => Some("stdweb: failed to get randomness"),
- RAND_SECURE_FATAL => Some("randSecure: random number generator module is not initialized"),
+ Error::UNSUPPORTED => Some("getrandom: this target is not supported"),
+ Error::ERRNO_NOT_POSITIVE => Some("errno: did not return a positive value"),
+ Error::IOS_SEC_RANDOM => Some("SecRandomCopyBytes: iOS Security framework failure"),
+ Error::WINDOWS_RTL_GEN_RANDOM => Some("RtlGenRandom: Windows system function failure"),
+ Error::FAILED_RDRAND => Some("RDRAND: failed multiple times: CPU issue likely"),
+ Error::NO_RDRAND => Some("RDRAND: instruction not supported"),
+ Error::WEB_CRYPTO => Some("Web API self.crypto is unavailable"),
+ Error::WEB_GET_RANDOM_VALUES => Some("Web API crypto.getRandomValues is unavailable"),
+ Error::VXWORKS_RAND_SECURE => Some("randSecure: VxWorks RNG module is not initialized"),
+ Error::NODE_CRYPTO => Some("Node.js crypto module is unavailable"),
+ Error::NODE_RANDOM_FILL_SYNC => Some("Node.js API crypto.randomFillSync is unavailable"),
_ => None,
}
}