use core::fmt;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum Error {
SecretTooShort {
actual: usize,
minimum: usize,
},
InvalidDigits {
actual: u8,
},
ZeroPeriod,
TimestampBeforeEpoch {
timestamp: u64,
epoch: u64,
},
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::SecretTooShort { actual, minimum } => write!(
f,
"shared secret is {actual} bytes; RFC 4226 requires at least {minimum}"
),
Self::InvalidDigits { actual } => {
write!(f, "invalid OTP width {actual}; expected 6, 7, or 8 digits")
}
Self::ZeroPeriod => f.write_str("TOTP period must be non-zero"),
Self::TimestampBeforeEpoch { timestamp, epoch } => write!(
f,
"Unix timestamp {timestamp} precedes the configured TOTP epoch {epoch}"
),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum CodeError {
InvalidLength {
actual: usize,
expected: u8,
},
NonDecimal {
index: usize,
},
}
impl fmt::Display for CodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidLength { actual, expected } => {
write!(f, "OTP is {actual} bytes; expected exactly {expected}")
}
Self::NonDecimal { index } => {
write!(f, "OTP contains a non-decimal byte at index {index}")
}
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for CodeError {}