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
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);
|
|
}
|
|
}
|