use core::convert::TryFrom;
use crate::Data;
impl Default for Status {
fn default() -> Self {
Status::Success
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum Status {
Success,
MoreAvailable(u8),
VerificationFailed,
RemainingRetries(u8),
UnspecifiedNonpersistentExecutionError,
UnspecifiedPersistentExecutionError,
WrongLength,
LogicalChannelNotSupported,
SecureMessagingNotSupported,
CommandChainingNotSupported,
SecurityStatusNotSatisfied,
ConditionsOfUseNotSatisfied,
OperationBlocked,
IncorrectDataParameter,
FunctionNotSupported,
NotFound,
NotEnoughMemory,
IncorrectP1OrP2Parameter,
KeyReferenceNotFound,
InstructionNotSupportedOrInvalid,
ClassNotSupported,
UnspecifiedCheckingError,
}
impl TryFrom<(u8, u8)> for Status {
type Error = u16;
#[inline]
fn try_from(sw: (u8, u8)) -> Result<Self, Self::Error> {
let (sw1, sw2) = sw;
Ok(match u16::from_be_bytes([sw1, sw2]) {
0x6300 => Self::VerificationFailed,
sw @ 0x63c0..=0x63cf => Self::RemainingRetries((sw as u8) & 0xf),
0x6400 => Self::UnspecifiedNonpersistentExecutionError,
0x6500 => Self::UnspecifiedPersistentExecutionError,
0x6700 => Self::WrongLength,
0x6881 => Self::LogicalChannelNotSupported,
0x6882 => Self::SecureMessagingNotSupported,
0x6884 => Self::CommandChainingNotSupported,
0x6982 => Self::SecurityStatusNotSatisfied,
0x6985 => Self::ConditionsOfUseNotSatisfied,
0x6983 => Self::OperationBlocked,
0x6a80 => Self::IncorrectDataParameter,
0x6a81 => Self::FunctionNotSupported,
0x6a82 => Self::NotFound,
0x6a84 => Self::NotEnoughMemory,
0x6a86 => Self::IncorrectP1OrP2Parameter,
0x6a88 => Self::KeyReferenceNotFound,
0x6d00 => Self::InstructionNotSupportedOrInvalid,
0x6e00 => Self::ClassNotSupported,
0x6f00 => Self::UnspecifiedCheckingError,
0x9000 => Self::Success,
sw @ 0x6100..=0x61FF => Self::MoreAvailable(sw as u8),
other => return Err(other),
})
}
}
impl Into<u16> for Status {
#[inline]
fn into(self) -> u16 {
match self {
Self::VerificationFailed => 0x6300,
Self::RemainingRetries(x) => {
assert!(x < 16);
u16::from_be_bytes([0x63, 0xc0 + x])
}
Self::UnspecifiedNonpersistentExecutionError => 0x6400,
Self::UnspecifiedPersistentExecutionError => 0x6500,
Self::WrongLength => 0x6700,
Self::LogicalChannelNotSupported => 0x6881,
Self::SecureMessagingNotSupported => 0x6882,
Self::CommandChainingNotSupported => 0x6884,
Self::SecurityStatusNotSatisfied => 0x6982,
Self::ConditionsOfUseNotSatisfied => 0x6985,
Self::OperationBlocked => 0x6983,
Self::IncorrectDataParameter => 0x6a80,
Self::FunctionNotSupported => 0x6a81,
Self::NotFound => 0x6a82,
Self::NotEnoughMemory => 0x6a84,
Self::IncorrectP1OrP2Parameter => 0x6a86,
Self::KeyReferenceNotFound => 0x6a88,
Self::InstructionNotSupportedOrInvalid => 0x6d00,
Self::ClassNotSupported => 0x6e00,
Self::UnspecifiedCheckingError => 0x6f00,
Self::Success => 0x9000,
Self::MoreAvailable(x) => u16::from_be_bytes([0x61, x]),
}
}
}
impl Into<[u8; 2]> for Status {
#[inline]
fn into(self) -> [u8; 2] {
let sw: u16 = self.into();
sw.to_be_bytes()
}
}
impl<const S: usize> Into<Data<S>> for Status
{
#[inline]
fn into(self) -> Data<S> {
let arr: [u8; 2] = self.into();
Data::from_slice(&arr).unwrap()
}
}