diff --git a/src/id_store.rs b/src/id_store.rs index 2ce4bf9..3bacedc 100644 --- a/src/id_store.rs +++ b/src/id_store.rs @@ -1,4 +1,3 @@ -use log::info; use serde::{Deserialize, Serialize}; use std::{ collections::{HashMap, HashSet}, @@ -44,11 +43,15 @@ impl IDStore { } /// Add a new id for the current day - /// Duplicates will get ignored - pub fn add_id(&mut self, id: TallyID) { - let day = self.get_current_day(); + /// Returns false if ID is already present at the current day. + /// Can fail because the store will be saved to a file. + pub fn add_id(&mut self, id: TallyID) -> Result> { + if self.get_current_day().add_id(id) { + self.export_json("./data.json")?; + return Ok(true); + } - day.add_id(id); + Ok(false) } /// Get the `AttendanceDay` of the current day @@ -126,12 +129,14 @@ impl AttendanceDay { } } - fn add_id(&mut self, id: TallyID) { + // Add an ID to the day. + // Returns false if ID was already present + fn add_id(&mut self, id: TallyID) -> bool { if self.ids.contains(&id) { - return; + return false; } - info!("Adding id: {}", id); self.ids.push(id); + true } } diff --git a/src/main.rs b/src/main.rs index a3ed1fe..307a5be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,19 @@ use id_store::IDStore; -use log::{LevelFilter, error, info, warn}; +use log::{LevelFilter, debug, error, info, warn}; use pm3::{pm3_mock, run_pm3}; use simplelog::{ConfigBuilder, SimpleLogger}; use std::{env, error::Error, sync::Arc}; -use tokio::{fs, sync::{mpsc, Mutex}}; +use tokio::{ + fs, + sync::{Mutex, mpsc}, +}; use webserver::start_webserver; mod id_store; mod parser; mod pm3; mod webserver; + const STORE_PATH: &str = "./data.json"; fn setup_logger() { @@ -32,7 +36,7 @@ fn setup_logger() { } #[tokio::main] -async fn main() -> Result<(),Box>{ +async fn main() -> Result<(), Box> { setup_logger(); info!("Starting application"); @@ -50,11 +54,10 @@ async fn main() -> Result<(),Box>{ } }); - let raw_store = if fs::try_exists(STORE_PATH).await? { info!("Loading data from file"); IDStore::new_from_json(STORE_PATH)? - }else { + } else { info!("No data file found. Creating empty one."); IDStore::new() }; @@ -64,7 +67,22 @@ async fn main() -> Result<(),Box>{ let channel_store = store.clone(); tokio::spawn(async move { while let Some(tally_id_string) = rx.recv().await { - channel_store.lock().await.add_id(id_store::TallyID(tally_id_string)); + match channel_store + .lock() + .await + .add_id(id_store::TallyID(tally_id_string)) + { + Ok(added) => { + if added { + debug!("~Beep~ Added new ID"); + // TODO: Add buzzer here + } + } + Err(e) => { + error!("Failed to save id to the store: {}", e); + // TODO: What to do if the ID could not be saved ? + } + } } }); @@ -74,5 +92,6 @@ async fn main() -> Result<(),Box>{ error!("Failed to start webserver: {}", e); } } + Ok(()) }