diff options
author | Robin Krahl <robin.krahl@ireas.org> | 2020-07-14 21:43:37 +0200 |
---|---|---|
committer | Robin Krahl <robin.krahl@ireas.org> | 2020-07-14 21:43:37 +0200 |
commit | d0f517eec5fbeb402a42eb2b23ca13fc85f1bc98 (patch) | |
tree | 1bba179f71828cb9e0004c82ed991fe22cddf3f2 | |
parent | cf460cbb5e616d12f5e6b1f64acddf3ec0e7b087 (diff) | |
parent | f1e83eb81879412e1de9898238ba58289bb6cb24 (diff) | |
download | nitrokey-rs-d0f517eec5fbeb402a42eb2b23ca13fc85f1bc98.tar.gz nitrokey-rs-d0f517eec5fbeb402a42eb2b23ca13fc85f1bc98.tar.bz2 |
Merge branch 'poison-error' into next
This patch series refactors the Error enum and ensures that it is Send,
Sync and 'static. This makes sure that it is compatible with the anyhow
crate. To achieve this, we drop the RandError variant and remove the
sync::PoisonError value from the PoisonError variant.
-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. |