diff options
| -rw-r--r-- | CHANGELOG.md | 5 | ||||
| -rw-r--r-- | src/error.rs | 39 | ||||
| -rw-r--r-- | src/lib.rs | 11 | 
3 files changed, 36 insertions, 19 deletions
| diff --git a/CHANGELOG.md b/CHANGELOG.md index e2dd8a7..651a50e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ Copyright (C) 2019-2020 Robin Krahl <robin.krahl@ireas.org>  SPDX-License-Identifier: CC0-1.0  --> +# Unreleased +- Refactor the `Error` enum so that it is `Send`, `Sync` and `'static`: +  - Remove the `sync::PoisonError` from the `PoisonError` variant. +  - Remove `Error::RandError` variant. +  # v0.6.0 (2020-02-03)  - Add `String` value to the `Error::UnexpectedError` variant.  - Always store serial numbers as structs: diff --git a/src/error.rs b/src/error.rs index 7bea3f2..1aa1793 100644 --- a/src/error.rs +++ b/src/error.rs @@ -21,9 +21,7 @@ pub enum Error {      /// A library usage error.      LibraryError(LibraryError),      /// An error that occurred due to a poisoned lock. -    PoisonError(sync::PoisonError<sync::MutexGuard<'static, crate::Manager>>), -    /// An error that occurred during random number generation. -    RandError(Box<dyn error::Error>), +    PoisonError,      /// An error that is caused by an unexpected value returned by libnitrokey.      UnexpectedError(String),      /// An unknown error returned by libnitrokey. @@ -72,14 +70,14 @@ impl From<str::Utf8Error> for Error {      }  } -impl From<sync::PoisonError<sync::MutexGuard<'static, crate::Manager>>> for Error { -    fn from(error: sync::PoisonError<sync::MutexGuard<'static, crate::Manager>>) -> Self { -        Error::PoisonError(error) +impl<T> From<sync::PoisonError<T>> for Error { +    fn from(_error: sync::PoisonError<T>) -> Self { +        Error::PoisonError      }  } -impl From<sync::TryLockError<sync::MutexGuard<'static, crate::Manager>>> for Error { -    fn from(error: sync::TryLockError<sync::MutexGuard<'static, crate::Manager>>) -> Self { +impl<T> From<sync::TryLockError<T>> for Error { +    fn from(error: sync::TryLockError<T>) -> Self {          match error {              sync::TryLockError::Poisoned(err) => err.into(),              sync::TryLockError::WouldBlock => Error::ConcurrentAccessError, @@ -100,8 +98,7 @@ impl error::Error for Error {              Error::CommunicationError(ref err) => Some(err),              Error::ConcurrentAccessError => None,              Error::LibraryError(ref err) => Some(err), -            Error::PoisonError(ref err) => Some(err), -            Error::RandError(ref err) => Some(err.as_ref()), +            Error::PoisonError => None,              Error::UnexpectedError(_) => None,              Error::UnknownError(_) => None,              Error::UnsupportedModelError => None, @@ -117,8 +114,7 @@ impl fmt::Display for Error {              Error::CommunicationError(ref err) => write!(f, "Communication error: {}", err),              Error::ConcurrentAccessError => write!(f, "Internal error: concurrent access"),              Error::LibraryError(ref err) => write!(f, "Library error: {}", err), -            Error::PoisonError(_) => write!(f, "Internal error: poisoned lock"), -            Error::RandError(ref err) => write!(f, "RNG error: {}", err), +            Error::PoisonError => write!(f, "Internal error: poisoned lock"),              Error::UnexpectedError(ref s) => write!(f, "An unexpected error occurred: {}", s),              Error::UnknownError(ref err) => write!(f, "Unknown error: {}", err),              Error::UnsupportedModelError => write!(f, "Unsupported Nitrokey model"), @@ -271,3 +267,22 @@ impl fmt::Display for LibraryError {          })      }  } + +// build our own static assertion that Error implements error::Error, Send, Sync, 'static + +struct Helper<T>(T); + +trait Assert { +    fn assert() -> bool; +} + +impl<T: error::Error + Send + Sync + 'static> Assert for Helper<T> { +    fn assert() -> bool { +        true +    } +} + +#[allow(unused)] +fn assert_error_impl() { +    let _ = Helper::<Error>::assert(); +} @@ -470,13 +470,10 @@ pub fn take() -> Result<sync::MutexGuard<'static, Manager>, Error> {  /// [`ConcurrentAccessError`]: struct.Error.html#variant.ConcurrentAccessError  /// [`Manager`]: struct.Manager.html  pub fn force_take() -> Result<sync::MutexGuard<'static, Manager>, Error> { -    match take() { -        Ok(guard) => Ok(guard), -        Err(err) => match err { -            Error::PoisonError(err) => Ok(err.into_inner()), -            err => Err(err), -        }, -    } +    MANAGER.try_lock().or_else(|err| match err { +        sync::TryLockError::Poisoned(err) => Ok(err.into_inner()), +        sync::TryLockError::WouldBlock => Err(Error::ConcurrentAccessError), +    })  }  /// List all connected Nitrokey devices. | 
