use std::{fs::{read_to_string, write}}; use serde::{Deserialize, Serialize}; use crate::{device::{device::{get_device_types, DeviceType}, Device}, device_repo::error::RepoError}; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Repo { #[serde(default)] hr_sensors: Vec, #[serde(default)] cad_sensors: Vec, #[serde(default)] trainers: Vec } impl Repo { pub fn new() -> Self { Self { hr_sensors: Vec::new(), cad_sensors: Vec::new(), trainers: Vec::new(), } } } const STATIC_PATH: &str = "devices.json"; pub fn try_write(repo: &Repo) -> Result { let json = serde_json::to_string_pretty(repo)?; write(STATIC_PATH, json)?; Ok(repo.clone()) } pub fn try_from_file() -> Result { let contents = match read_to_string(STATIC_PATH) { Ok(s) if !s.trim().is_empty() => s, _ => return Err(RepoError::Empty), }; let repo: Repo = serde_json::from_str(&contents)?; Ok(repo) } pub fn repo_from_devices(devices: Vec) -> Repo { let mut repo = Repo::new(); for dev in devices.into_iter() { let types = get_device_types(&dev); for t in types { match t { DeviceType::HrSensor => repo.hr_sensors.push(dev.clone()), DeviceType::CadSensor => repo.cad_sensors.push(dev.clone()), DeviceType::Trainer => repo.trainers.push(dev.clone()), } } } fn sort_by_rssi_desc(v: &mut [Device]) { v.sort_by(|a, b| { let ra = a.rssi; let rb = b.rssi; match (ra, rb) { (Some(va), Some(vb)) => vb.cmp(&va), (Some(_), None) => std::cmp::Ordering::Less, (None, Some(_)) => std::cmp::Ordering::Greater, (None, None) => std::cmp::Ordering::Equal, } }); } sort_by_rssi_desc(&mut repo.hr_sensors); sort_by_rssi_desc(&mut repo.cad_sensors); sort_by_rssi_desc(&mut repo.trainers); repo } #[cfg(test)] mod tests { use super::*; #[test] fn test_service_types_for_magene_speedcadence() { let magene = Device { id: "hci0/dev_F1_F2_7C_77_14_BE".into(), address: "F1:F2:7C:77:14:BE".into(), display_name: Some("10911-17".into()), rssi: Some(-42), service_uuids: vec!["00001816-0000-1000-8000-00805f9b34fb".into()], characteristics: vec![], manufacturer_data: Some("6b009f2a110300030072".into()), metadata: None, }; let devices = vec![magene]; let x = repo_from_devices(devices); println!("{:?}", x); //assert_eq!(repo_from_devices(devices), Repo::new()); assert_eq!(2, 3); } }