use std::fmt::{Display, Formatter, Result};
use tokio::sync::oneshot::Sender;
use zbus::zvariant::OwnedObjectPath;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum AgentCapability {
DisplayYesNo,
DisplayOnly,
KeyboardOnly,
#[default]
KeyboardDisplay,
NoInputNoOutput,
}
impl From<&str> for AgentCapability {
fn from(s: &str) -> Self {
match s {
"DisplayYesNo" => Self::DisplayYesNo,
"DisplayOnly" => Self::DisplayOnly,
"KeyboardOnly" => Self::KeyboardOnly,
"KeyboardDisplay" => Self::KeyboardDisplay,
"NoInputNoOutput" => Self::NoInputNoOutput,
"" => Self::KeyboardDisplay,
_ => Self::KeyboardDisplay,
}
}
}
impl Display for AgentCapability {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
match self {
Self::DisplayYesNo => write!(f, "DisplayYesNo"),
Self::DisplayOnly => write!(f, "DisplayOnly"),
Self::KeyboardOnly => write!(f, "KeyboardOnly"),
Self::KeyboardDisplay => write!(f, "KeyboardDisplay"),
Self::NoInputNoOutput => write!(f, "NoInputNoOutput"),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum PairingRequest {
RequestPinCode {
device_path: OwnedObjectPath,
},
DisplayPinCode {
device_path: OwnedObjectPath,
pincode: String,
},
RequestPasskey {
device_path: OwnedObjectPath,
},
DisplayPasskey {
device_path: OwnedObjectPath,
passkey: u32,
entered: u16,
},
RequestConfirmation {
device_path: OwnedObjectPath,
passkey: u32,
},
RequestAuthorization {
device_path: OwnedObjectPath,
},
RequestServiceAuthorization {
device_path: OwnedObjectPath,
uuid: String,
},
}
#[derive(Debug)]
pub(crate) enum PairingResponder {
Pin(Sender<String>),
Passkey(Sender<u32>),
Confirmation(Sender<bool>),
Authorization(Sender<bool>),
ServiceAuthorization(Sender<bool>),
}
#[derive(Debug)]
pub(crate) enum AgentEvent {
PinRequested {
device_path: OwnedObjectPath,
responder: Sender<String>,
},
DisplayPinCode {
device_path: OwnedObjectPath,
pincode: String,
},
PasskeyRequested {
device_path: OwnedObjectPath,
responder: Sender<u32>,
},
DisplayPasskey {
device_path: OwnedObjectPath,
passkey: u32,
entered: u16,
},
ConfirmationRequested {
device_path: OwnedObjectPath,
passkey: u32,
responder: Sender<bool>,
},
AuthorizationRequested {
device_path: OwnedObjectPath,
responder: Sender<bool>,
},
ServiceAuthorizationRequested {
device_path: OwnedObjectPath,
uuid: String,
responder: Sender<bool>,
},
Cancelled,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn agent_capability_from_str_handles_all_variants() {
assert_eq!(
AgentCapability::from("DisplayYesNo"),
AgentCapability::DisplayYesNo
);
assert_eq!(
AgentCapability::from("DisplayOnly"),
AgentCapability::DisplayOnly
);
assert_eq!(
AgentCapability::from("KeyboardOnly"),
AgentCapability::KeyboardOnly
);
assert_eq!(
AgentCapability::from("KeyboardDisplay"),
AgentCapability::KeyboardDisplay
);
assert_eq!(
AgentCapability::from("NoInputNoOutput"),
AgentCapability::NoInputNoOutput
);
}
#[test]
fn agent_capability_from_empty_string_returns_keyboard_display() {
assert_eq!(AgentCapability::from(""), AgentCapability::KeyboardDisplay);
}
#[test]
fn agent_capability_from_unknown_defaults_to_keyboard_display() {
assert_eq!(
AgentCapability::from("unknown"),
AgentCapability::KeyboardDisplay
);
assert_eq!(
AgentCapability::from("invalid"),
AgentCapability::KeyboardDisplay
);
}
}