Skip to content

Commit

Permalink
Add new error types from dhardy/master branch
Browse files Browse the repository at this point in the history
Design: #10
  • Loading branch information
dhardy committed Jan 9, 2018
1 parent 0f3c532 commit 1136240
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 0 deletions.
139 changes: 139 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// Copyright 2017-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Error types

use core::fmt;

#[cfg(feature="std")]
use std::error::Error as stdError;

/// Error kind which can be matched over.
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum ErrorKind {
/// Permanent failure: likely not recoverable without user action.
Unavailable,
/// Temporary failure: recommended to retry a few times, but may also be
/// irrecoverable.
Transient,
/// Not ready yet: recommended to try again a little later.
NotReady,
/// Uncategorised error
Other,
#[doc(hidden)]
__Nonexhaustive,
}

impl ErrorKind {
/// True if this kind of error may resolve itself on retry.
///
/// See also `should_wait()`.
pub fn should_retry(self) -> bool {
match self {
ErrorKind::Transient | ErrorKind::NotReady => true,
_ => false,
}
}

/// True if we should retry but wait before retrying
///
/// This implies `should_retry()` is true.
pub fn should_wait(self) -> bool {
self == ErrorKind::NotReady
}

/// A description of this error kind
pub fn description(self) -> &'static str {
match self {
ErrorKind::Unavailable => "permanent failure or unavailable",
ErrorKind::Transient => "transient failure",
ErrorKind::NotReady => "not ready yet",
ErrorKind::Other => "uncategorised",
ErrorKind::__Nonexhaustive => unreachable!(),
}
}
}

/// Error type of random number generators
///
/// This is a relatively simple error type, designed for compatibility with and
/// without the Rust `std` library. It embeds a "kind" code, a message (static
/// string only), and an optional chained cause (`std` only).
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
msg: &'static str,
#[cfg(feature="std")]
cause: Option<Box<stdError + Send + Sync>>,
}

impl Error {
/// Create a new instance, with specified kind and a message.
pub fn new(kind: ErrorKind, msg: &'static str) -> Self {
#[cfg(feature="std")] {
Self { kind, msg, cause: None }
}
#[cfg(not(feature="std"))] {
Self { kind, msg }
}
}

/// Create a new instance, with specified kind, 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.
#[cfg(feature="std")]
pub fn with_cause<E>(kind: ErrorKind, msg: &'static str, cause: E) -> Self
where E: Into<Box<stdError + Send + Sync>>
{
Self { kind, msg, cause: Some(cause.into()) }
}

/// Create a new instance, with specified kind, message, and a
/// chained cause.
///
/// In `no_std` mode the *cause* is ignored.
#[cfg(not(feature="std"))]
pub fn with_cause<E>(kind: ErrorKind, msg: &'static str, _cause: E) -> Self {
Self { kind, msg }
}

/// Get the error kind
pub fn kind(&self) -> ErrorKind {
self.kind
}

/// Get the error message
pub fn msg(&self) -> &'static str {
self.msg
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "RNG error [{}]: {}", self.kind.description(), self.msg())
}
}

#[cfg(feature="std")]
impl stdError for Error {
fn description(&self) -> &str {
self.msg
}

fn cause(&self) -> Option<&stdError> {
self.cause.as_ref().map(|e| e.as_ref() as &stdError)
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ pub use isaac::{IsaacRng, Isaac64Rng};
pub use chacha::ChaChaRng;
pub use prng::XorShiftRng;

// error types
pub use error::{ErrorKind, Error};

// local use declarations
#[cfg(target_pointer_width = "32")]
use prng::IsaacRng as IsaacWordRng;
Expand Down Expand Up @@ -294,6 +297,7 @@ pub mod isaac {
}

// private modules
mod error;
mod rand_impls;
mod prng;

Expand Down

0 comments on commit 1136240

Please sign in to comment.