You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
2.8 KiB

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<Device>,
#[serde(default)]
cad_sensors: Vec<Device>,
#[serde(default)]
trainers: Vec<Device>
}
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<Repo, RepoError> {
let json = serde_json::to_string_pretty(repo)?;
write(STATIC_PATH, json)?;
Ok(repo.clone())
}
pub fn try_from_file() -> Result<Repo, RepoError> {
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<Device>) -> 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);
}
}