Crate apdu_derive
source ·Expand description
Implementation of procedural macro for apdu crate. By deriving apdu_derive::Response, you can convert from APDU raw response to an Enum easily. Macro interface is inspired by thiserror crate.
Examples
Here is a simple example to derive Response:
#[derive(apdu_derive::Response)]
enum Response<'a> {
#[apdu(0x90, 0x00)]
Ok(&'a [u8]),
#[apdu(0x60..=0x69, _)]
#[apdu(0x12, 0x34)]
NotOk,
#[apdu(_, _)]
Unknown(u8, u8),
}
This is equivalent to implementing this:
enum Response<'a> {
Ok(&'a [u8]),
NotOk,
Unknown(u8, u8),
}
impl<'a> From<apdu_core::Response<'a>> for Response<'a> {
fn from(response: apdu_core::Response<'a>) -> Self {
match response.trailer {
(0x90, 0x00) => Self::Ok(response.payload),
(0x60..=0x69, _) => Self::NotOk,
(_, _) => Self::Unknown(response.trailer.0, response.trailer.1),
}
}
}
Also you can combine them with thiserror derive:
#[derive(Debug, apdu_derive::Response, thiserror::Error)]
enum Response {
#[apdu(0x60..=0x69, _)]
#[error("not ok!")]
NotOk,
#[apdu(_, _)]
#[error("unknown: {0:#X} {1:#X}")]
Unknown(u8, u8),
}
Optionally you can select what to inject to the fields:
#[derive(Debug, apdu_derive::Response, thiserror::Error)]
enum Response {
#[apdu(0x63, 0xC0..=0xCF)]
#[error("verify failed: {0} tries left")]
VerifyFailed(#[sw2] #[mask(0x0F)] u8),
#[apdu(_, _)]
#[error("unknown: {0:#X} {1:#X}")]
Unknown(u8, u8),
}