diff --git a/src/main.rs b/src/main.rs index 47fac5d..e4774b0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,9 @@ use chrono::{Local, Timelike}; use clap::Parser; -use serde::{de, Deserialize, Deserializer}; -use std::{ - error::Error, - fs, - path::{Path, PathBuf}, -}; -use toml::value::Datetime; +use std::{error::Error, path::PathBuf}; +use sunrise::Sunrise; + +mod sunrise; #[derive(Parser)] #[command(version, about, long_about = None)] @@ -15,78 +12,6 @@ struct Cli { file: PathBuf, } -#[derive(Deserialize, Debug)] -struct Sunrise { - /// Sorted array of Timetables - schedule: Vec, -} - -#[derive(Deserialize, Debug)] -struct Timetable { - /// Time of day in seconds from 0:00 - #[serde(deserialize_with = "deserialize_seconds")] - time: u32, - image: PathBuf, -} - -impl Sunrise { - fn load_from_file(path: &Path) -> Result> { - let file = fs::read_to_string(path)?; - let mut data: Sunrise = toml::from_str(&file)?; - - data.schedule.sort_by_key(|e| e.time); - - Ok(data) - } - - fn closest_passed_time(&self, current: u32) -> Option<&Timetable> { - let idx = match self - .schedule - .binary_search_by_key(¤t, |time| time.time) - { - Ok(idx) => idx, - Err(idx) => idx, - }; - - if idx > 0 { - return Some(&self.schedule[idx - 1]); // Return the time before the current time - } else if !self.schedule.is_empty() { - return self.schedule.last(); // Wrap around to the last time if current time is before the first time - } else { - return None; // Return None if the times array is empty - } - } -} - -impl Timetable { - fn get_absolute_image_path(&self, config_path: &Path) -> PathBuf { - if self.image.is_absolute() { - return self.image.clone(); - } - - return config_path.join(&self.image); - } -} - -fn deserialize_seconds<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let datetime: Datetime = Deserialize::deserialize(deserializer)?; - - match datetime.time { - Some(time) => { - let h: u32 = time.hour.into(); - let m: u32 = time.minute.into(); - let s: u32 = time.second.into(); - - return Ok(h * 3600 + m * 60 + s); - } - - None => return Err(de::Error::custom("Must include a time of day")), - } -} - fn main() -> Result<(), Box> { let cli = Cli::parse(); diff --git a/src/sunrise.rs b/src/sunrise.rs new file mode 100644 index 0000000..755909e --- /dev/null +++ b/src/sunrise.rs @@ -0,0 +1,79 @@ +use serde::{de, Deserialize, Deserializer}; +use std::{ + error::Error, + fs, + path::{Path, PathBuf}, +}; +use toml::value::Datetime; + +#[derive(Deserialize, Debug)] +pub struct Sunrise { + /// Sorted array of Timetables + schedule: Vec, +} + +#[derive(Deserialize, Debug)] +pub struct Timetable { + /// Time of day in seconds from 0:00 + #[serde(deserialize_with = "deserialize_seconds")] + time: u32, + image: PathBuf, +} + +impl Sunrise { + pub fn load_from_file(path: &Path) -> Result> { + let file = fs::read_to_string(path)?; + let mut data: Sunrise = toml::from_str(&file)?; + + data.schedule.sort_by_key(|e| e.time); + + Ok(data) + } + + pub fn closest_passed_time(&self, current: u32) -> Option<&Timetable> { + let idx = match self + .schedule + .binary_search_by_key(¤t, |time| time.time) + { + Ok(idx) => idx, + Err(idx) => idx, + }; + + if idx > 0 { + return Some(&self.schedule[idx - 1]); // Return the time before the current time + } else if !self.schedule.is_empty() { + return self.schedule.last(); // Wrap around to the last time if current time is before the first time + } else { + return None; // Return None if the times array is empty + } + } +} + +impl Timetable { + pub fn get_absolute_image_path(&self, config_path: &Path) -> PathBuf { + if self.image.is_absolute() { + return self.image.clone(); + } + + return config_path.join(&self.image); + } +} + +fn deserialize_seconds<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let datetime: Datetime = Deserialize::deserialize(deserializer)?; + + match datetime.time { + Some(time) => { + let h: u32 = time.hour.into(); + let m: u32 = time.minute.into(); + let s: u32 = time.second.into(); + + return Ok(h * 3600 + m * 60 + s); + } + + None => return Err(de::Error::custom("Must include a time of day")), + } +}