use async_trait::async_trait;
use crate::lan_pair::{LanPairError, PairAccept, PairOffer};
#[async_trait]
pub trait ConfirmationStrategy: Send + Sync {
async fn confirm(&self, offer: &PairOffer) -> Result<Option<PairAccept>, LanPairError>;
}
pub struct AutoTrust {
pub accept: PairAccept,
}
#[async_trait]
impl ConfirmationStrategy for AutoTrust {
async fn confirm(&self, _offer: &PairOffer) -> Result<Option<PairAccept>, LanPairError> {
Ok(Some(self.accept.clone()))
}
}
pub struct SixDigitCode {
pub accept: PairAccept,
pub prompt: Box<dyn Fn(&PairOffer) -> String + Send + Sync>,
}
#[async_trait]
impl ConfirmationStrategy for SixDigitCode {
async fn confirm(&self, offer: &PairOffer) -> Result<Option<PairAccept>, LanPairError> {
let expected = offer
.code
.as_deref()
.ok_or_else(|| LanPairError::Codec("PairOffer missing code for SixDigitCode strategy".into()))?;
let entered = (self.prompt)(offer);
if entered.trim() == expected.trim() {
Ok(Some(self.accept.clone()))
} else {
Ok(None)
}
}
}
pub struct DisplayCode {
pub accept: PairAccept,
pub display: Box<dyn Fn(&PairOffer, &str) -> bool + Send + Sync>,
}
#[async_trait]
impl ConfirmationStrategy for DisplayCode {
async fn confirm(&self, offer: &PairOffer) -> Result<Option<PairAccept>, LanPairError> {
let code = offer.code.as_deref().unwrap_or("");
if (self.display)(offer, code) {
Ok(Some(self.accept.clone()))
} else {
Ok(None)
}
}
}