use crate::ocard::data::{ApplicationRelatedData, KdfDo};
use crate::{Cached, Card};
pub trait State {}
impl State for Open {}
impl State for Transaction<'_> {}
impl State for User<'_, '_> {}
impl State for Sign<'_, '_> {}
impl State for Admin<'_, '_> {}
pub struct Open {
pub(crate) pgp: crate::ocard::OpenPGP,
}
pub struct Transaction<'a> {
pub(crate) opt: crate::ocard::Transaction<'a>,
ard: Cached<ApplicationRelatedData>,
kdf_do: Cached<KdfDo>,
pub(crate) pw1: bool,
pub(crate) pw1_sign: bool,
pub(crate) pw3: bool,
}
impl<'a> Transaction<'a> {
pub(crate) fn new(opt: crate::ocard::Transaction<'a>, ard: ApplicationRelatedData) -> Self {
Transaction {
opt,
ard: Cached::Value(ard),
kdf_do: Cached::Uncached,
pw1: false,
pw1_sign: false,
pw3: false,
}
}
pub(crate) fn ard(&mut self) -> &ApplicationRelatedData {
if matches!(self.ard, Cached::Uncached) {
match self.opt.application_related_data() {
Ok(ard) => {
self.ard = Cached::Value(ard);
}
Err(_) => {
self.ard = Cached::None;
}
}
}
match &self.ard {
Cached::Value(ard) => ard,
Cached::Uncached => unreachable!(),
Cached::None => unreachable!(),
}
}
pub(crate) fn kdf_do(&mut self) -> Option<&KdfDo> {
if matches!(self.kdf_do, Cached::Uncached) {
match self.opt.kdf_do() {
Ok(kdf) => {
self.kdf_do = Cached::Value(kdf.clone());
}
Err(_) => {
self.kdf_do = Cached::None;
}
}
}
match &self.kdf_do {
Cached::None => None,
Cached::Value(kdf) => Some(kdf),
Cached::Uncached => unreachable!(),
}
}
pub(crate) fn invalidate_cache(&mut self) {
self.ard = Cached::Uncached;
self.kdf_do = Cached::Uncached;
}
}
pub struct User<'app, 'open> {
pub(crate) tx: &'open mut Card<Transaction<'app>>,
}
pub struct Sign<'app, 'open> {
pub(crate) tx: &'open mut Card<Transaction<'app>>,
}
pub struct Admin<'app, 'open> {
pub(crate) tx: &'open mut Card<Transaction<'app>>,
}