fuchsia_bluetooth/types/
pairing_options.rsuse fidl_fuchsia_bluetooth_sys as sys;
use crate::types::Technology;
#[derive(Clone, Debug, PartialEq)]
pub struct PairingOptions {
pub le_security_level: SecurityLevel,
pub bondable: BondableMode,
pub transport: Technology,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SecurityLevel {
Encrypted,
Authenticated,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum BondableMode {
Bondable,
NonBondable,
}
impl From<sys::PairingSecurityLevel> for SecurityLevel {
fn from(level: sys::PairingSecurityLevel) -> Self {
match level {
sys::PairingSecurityLevel::Encrypted => SecurityLevel::Encrypted,
sys::PairingSecurityLevel::Authenticated => SecurityLevel::Authenticated,
}
}
}
impl From<SecurityLevel> for sys::PairingSecurityLevel {
fn from(level: SecurityLevel) -> Self {
match level {
SecurityLevel::Encrypted => sys::PairingSecurityLevel::Encrypted,
SecurityLevel::Authenticated => sys::PairingSecurityLevel::Authenticated,
}
}
}
impl From<sys::PairingOptions> for PairingOptions {
fn from(opts: sys::PairingOptions) -> Self {
(&opts).into()
}
}
impl From<&sys::PairingOptions> for PairingOptions {
fn from(opts: &sys::PairingOptions) -> Self {
let bondable = match opts.bondable_mode {
Some(sys::BondableMode::NonBondable) => BondableMode::NonBondable,
Some(sys::BondableMode::Bondable) | None => BondableMode::Bondable,
};
let le_security_level =
opts.le_security_level.map_or(SecurityLevel::Encrypted, SecurityLevel::from);
let transport = opts.transport.map_or(Technology::DualMode, Technology::from);
PairingOptions { le_security_level, bondable, transport }
}
}
impl From<&PairingOptions> for sys::PairingOptions {
fn from(opts: &PairingOptions) -> Self {
let bondable_mode = match opts.bondable {
BondableMode::NonBondable => Some(sys::BondableMode::NonBondable),
BondableMode::Bondable => Some(sys::BondableMode::Bondable),
};
let le_security_level = Some(opts.le_security_level.into());
let transport = Some(opts.transport.into());
sys::PairingOptions { le_security_level, bondable_mode, transport, ..Default::default() }
}
}
impl From<PairingOptions> for sys::PairingOptions {
fn from(opts: PairingOptions) -> Self {
(&opts).into()
}
}
#[cfg(test)]
pub mod tests {
use super::*;
use proptest::prelude::*;
fn any_technology() -> impl Strategy<Value = Technology> {
prop_oneof![Just(Technology::LE), Just(Technology::Classic), Just(Technology::DualMode)]
}
fn any_bondable() -> impl Strategy<Value = BondableMode> {
prop_oneof![Just(BondableMode::Bondable), Just(BondableMode::NonBondable)]
}
fn any_security() -> impl Strategy<Value = SecurityLevel> {
prop_oneof![Just(SecurityLevel::Encrypted), Just(SecurityLevel::Authenticated)]
}
prop_compose! {
fn any_pairing_options()(
le_security_level in any_security(),
bondable in any_bondable(),
transport in any_technology()) -> PairingOptions {
PairingOptions{ le_security_level, bondable, transport }
}
}
proptest! {
#[test]
fn roundtrip(opts in any_pairing_options()) {
let sys: sys::PairingOptions = (&opts).into();
assert_eq!(opts, sys.into());
}
}
}