Something went wrong. Try again.
Something went wrong. Try again.
3.0 kB · 114 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115use std::{collections::HashMap, ops::Not, path::PathBuf, sync::Arc};
use color_eyre::eyre::{Result, eyre};use serde::{Deserialize, Serialize};use tokio::{fs, sync::RwLock};
#[derive(Debug, Clone, Serialize, Deserialize)]pub struct Device { pub ip: [u8; 4], pub port: u16, pub mode: Mode, pub color: String, pub sun_brightness: u8,}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]pub enum Mode { #[default] #[serde(rename = "color")] Color, #[serde(rename = "sun")] Sun, #[serde(rename = "off")] Off,}
#[derive(Debug, Clone)]pub struct DeviceStorage { path: PathBuf, pub devices: Arc<RwLock<HashMap<String, Device>>>,}
impl DeviceStorage { pub async fn load(path: PathBuf) -> Result<DeviceStorage> { if path.exists().not() { return Ok(DeviceStorage { path, devices: Arc::new(RwLock::new(HashMap::new())), }); }
let content = fs::read_to_string(&path).await?; let devices: HashMap<String, Device> = serde_json::from_str(&content)?;
Ok(DeviceStorage { path, devices: Arc::new(RwLock::new(devices)), }) }
async fn save(&self) -> Result<()> { let content = serde_json::to_string(&*self.devices.read().await)?; fs::write(&self.path, content).await?; Ok(()) }
pub async fn get(&self, id: &str) -> Option<Device> { let registered_devices = self.devices.read().await; registered_devices.get(id).cloned() }
pub async fn get_all(&self) -> Vec<(String, Device)> { let registered_devices = self.devices.read().await; registered_devices .iter() .map(|(id, device)| (id.clone(), device.clone())) .collect() }
pub async fn update_or_insert(&self, id: String, new_device: Device) -> Result<Device> { let mut registered_devices = self.devices.write().await;
let device = registered_devices .entry(id) .and_modify(|current| { current.ip = new_device.ip; current.port = new_device.port; }) .or_insert(new_device) .clone();
// Drop the lock before saving to avoid blocking drop(registered_devices);
self.save().await?; Ok(device) }
pub async fn update_state( &self, id: &str, mode: Mode, color: String, sun_brightness: u8, ) -> Result<Option<Device>> { let mut registered_devices = self.devices.write().await;
let Some(device) = registered_devices.get_mut(id) else { return Ok(None); };
device.mode = mode; device.color = color; device.sun_brightness = sun_brightness;
let device = device.clone();
// Drop the lock before saving to avoid blocking drop(registered_devices);
self.save().await?; Ok(Some(device)) }}