From e31f1bca97fd8ee36bd933fa54c53980fc5084a7 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 5 Feb 2019 13:05:59 +0000 Subject: Add AuthenticationError --- CHANGELOG.md | 2 ++ src/error.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 4 +++- 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5d049c..e256fc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,8 @@ SPDX-License-Identifier: MIT - Add the `force_take` function that ignores a `PoisonError` when accessing the manager instance. - Internally refactor the `device` module into submodules. +- Refactor authentication: + - Add `AuthenticationError`. # v0.3.4 (2019-01-20) - Fix authentication methods that assumed that `char` is signed. diff --git a/src/error.rs b/src/error.rs index 9e6adc0..1b0edd4 100644 --- a/src/error.rs +++ b/src/error.rs @@ -3,6 +3,7 @@ use std::error; use std::fmt; +use std::marker; use std::os::raw; use std::str; use std::sync; @@ -46,6 +47,12 @@ impl From for Error { } } +impl<'a, T: crate::Device<'a>> From> for Error { + fn from(err: AuthenticationError<'a, T>) -> Self { + err.error + } +} + impl From for Error { fn from(err: CommandError) -> Self { Error::CommandError(err) @@ -267,3 +274,52 @@ impl fmt::Display for LibraryError { }) } } + +#[derive(Debug)] +pub struct AuthenticationError<'a, T: device::Device<'a>> { + error: Error, + device: T, + marker: marker::PhantomData>, +} + +impl<'a, T: device::Device<'a>> AuthenticationError<'a, T> { + pub fn new(error: Error, device: T) -> Self { + AuthenticationError { + error, + device, + marker: marker::PhantomData, + } + } + + pub fn as_error(&self) -> &Error { + &self.error + } + + pub fn into_device(self) -> T { + self.device + } + + pub fn map_device<'b, U, F>(self, op: F) -> AuthenticationError<'b, U> + where + U: device::Device<'b>, + F: Fn(T) -> U, + { + AuthenticationError { + error: self.error, + device: op(self.device), + marker: marker::PhantomData, + } + } +} + +impl<'a, T: device::Device<'a>> error::Error for AuthenticationError<'a, T> { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + Some(&self.error) + } +} + +impl<'a, T: device::Device<'a>> fmt::Display for AuthenticationError<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.error.fmt(f) + } +} diff --git a/src/lib.rs b/src/lib.rs index a4402c5..e3a2bc3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,7 +121,9 @@ pub use crate::device::{ Device, DeviceWrapper, Model, Pro, SdCardData, Storage, StorageProductionInfo, StorageStatus, VolumeMode, VolumeStatus, }; -pub use crate::error::{CommandError, CommunicationError, Error, LibraryError}; +pub use crate::error::{ + AuthenticationError, CommandError, CommunicationError, Error, LibraryError, +}; pub use crate::otp::{ConfigureOtp, GenerateOtp, OtpMode, OtpSlotData}; pub use crate::pws::{GetPasswordSafe, PasswordSafe, SLOT_COUNT}; pub use crate::util::LogLevel; -- cgit v1.2.1