aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2020-07-14 21:43:37 +0200
committerRobin Krahl <robin.krahl@ireas.org>2020-07-14 21:43:37 +0200
commitd0f517eec5fbeb402a42eb2b23ca13fc85f1bc98 (patch)
tree1bba179f71828cb9e0004c82ed991fe22cddf3f2
parentcf460cbb5e616d12f5e6b1f64acddf3ec0e7b087 (diff)
parentf1e83eb81879412e1de9898238ba58289bb6cb24 (diff)
downloadnitrokey-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.md5
-rw-r--r--src/error.rs39
-rw-r--r--src/lib.rs11
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();
+}
diff --git a/src/lib.rs b/src/lib.rs
index 3fa3ae3..5b72d63 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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.