pub mod device;
pub mod decryption;
pub mod types;
pub use device::{DeviceInfo, RawDevice, TransportType};
pub use decryption::Decryptor;
pub use types::*;
use anyhow::Result;
pub async fn discover_devices() -> Result<Vec<DeviceInfo>> {
RawDevice::discover().await
}
pub async fn connect_device(address: &str) -> Result<(tokio::sync::mpsc::Receiver<DecryptedData>, RawDevice)> {
let devices = discover_devices().await?;
let device = devices
.iter()
.find(|d| id_match(&d.address, address) || id_match(&d.serial, address))
.ok_or_else(|| anyhow::anyhow!("Device not found: {}", address))?;
let raw = RawDevice::from_info(device.clone());
let (rx, _handle) = raw.connect().await?;
Ok((rx, raw))
}
fn id_match(candidate: &str, input: &str) -> bool {
if candidate.eq_ignore_ascii_case(input) {
return true;
}
let a = normalize_id(candidate);
let b = normalize_id(input);
!a.is_empty() && !b.is_empty() && (a == b || a.contains(&b) || b.contains(&a))
}
fn normalize_id(s: &str) -> String {
s.chars()
.filter(|c| c.is_ascii_alphanumeric())
.flat_map(|c| c.to_lowercase())
.collect()
}