slauth 0.7.21

oath HOTP and TOTP complient implementation
Documentation
use ring::error::{KeyRejected, Unspecified};
#[cfg(feature = "u2f-server")]
use serde_json::error::Error as SJsonError;
use std::{
    error::Error as StdError,
    fmt::{Display, Formatter},
    io::Error as IoError,
};

#[derive(Debug)]
pub enum Error {
    IoError(IoError),
    U2FErrorCode(u16),
    UnexpectedApdu(String),
    AsnFormatError(String),
    MalformedApdu,
    Version,
    RingKeyRejected(KeyRejected),
    Registration(String),
    Sign(String),
    Other(String),
    #[cfg(feature = "u2f-server")]
    EndEntityError(webpki::Error),
    #[cfg(feature = "u2f-server")]
    SerdeJsonError(SJsonError),
}

impl StdError for Error {}

impl Display for Error {
    fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> {
        use Error::*;
        match self {
            IoError(io_e) => io_e.fmt(f),
            U2FErrorCode(code) => write!(f, "U2f Error Code: {}", code),
            UnexpectedApdu(s) => write!(f, "{}", s),
            AsnFormatError(s) => write!(f, "{}", s),
            MalformedApdu => write!(f, "Unsupported version"),
            Version => write!(f, "Unsupported version"),
            RingKeyRejected(key_r_e) => key_r_e.fmt(f),
            Registration(s) => write!(f, "{}", s),
            Sign(s) => write!(f, "{}", s),
            Other(s) => write!(f, "{}", s),
            #[cfg(feature = "u2f-server")]
            EndEntityError(webpki_e) => webpki_e.fmt(f),
            #[cfg(feature = "u2f-server")]
            SerdeJsonError(s_j_e) => s_j_e.fmt(f),
        }
    }
}

#[cfg(feature = "u2f-server")]
impl From<webpki::Error> for Error {
    fn from(e: webpki::Error) -> Self {
        Error::EndEntityError(e)
    }
}

impl From<IoError> for Error {
    fn from(e: IoError) -> Self {
        Error::IoError(e)
    }
}

impl From<u16> for Error {
    fn from(sw: u16) -> Self {
        Error::U2FErrorCode(sw)
    }
}

impl From<Unspecified> for Error {
    fn from(_: Unspecified) -> Self {
        Error::Other("Unspecified".to_string())
    }
}

impl From<KeyRejected> for Error {
    fn from(e: KeyRejected) -> Self {
        Error::RingKeyRejected(e)
    }
}

#[cfg(feature = "u2f-server")]
impl From<SJsonError> for Error {
    fn from(e: SJsonError) -> Self {
        Error::SerdeJsonError(e)
    }
}

pub trait ResultExt<T, E> {
    fn then<U, N, F>(self, op: F) -> Result<U, N>
    where
        F: FnOnce(Result<T, E>) -> Result<U, N>;
}

impl<T, E> ResultExt<T, E> for Result<T, E> {
    fn then<U, N, F>(self, op: F) -> Result<U, N>
    where
        F: FnOnce(Result<T, E>) -> Result<U, N>,
    {
        op(self)
    }
}