implemented more commands

This commit is contained in:
Niklas Kapelle 2024-03-30 00:10:18 +01:00
parent 09e06c57ea
commit 0681a8b8d1
Signed by: niklas
GPG Key ID: 4EB651B36D841D16
2 changed files with 114 additions and 20 deletions

View File

@ -1,5 +1,5 @@
use chrono::{Local, Timelike};
use clap::Parser;
use clap::{Parser, Subcommand};
use std::{error::Error, path::PathBuf};
use sunrise::Sunrise;
@ -8,31 +8,107 @@ mod sunrise;
#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
/// Sunrise file
file: PathBuf,
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Print the current wallpaper
Current {
/// Sunrise file
file: PathBuf,
},
/// Print the time to apply the next wallpaper
NextAt {
/// Sunrise file
file: PathBuf,
},
/// Print the time til the next wallpaper
NextIn {
/// Sunrise file
file: PathBuf,
/// Display time in seconds
#[arg(short,long)]
seconds: bool,
},
}
fn sec_to_readable(sec: u32) -> String {
let hours = sec / 3600;
let minutes = (sec % 3600) / 60;
let seconds = sec % 60;
format!("{:02}:{:02}:{:02}", hours, minutes, seconds)
}
fn main() -> Result<(), Box<dyn Error>> {
let cli = Cli::parse();
let sunrise = Sunrise::load_from_file(&cli.file)?;
match cli.command {
Commands::Current { file } => {
let sunrise = Sunrise::load_from_file(&file)?;
let now = Local::now();
let sec = now.hour() * 3600 + now.minute() * 60 + now.second();
match sunrise.closest_passed_time(sec) {
Some(timetable) => match file.canonicalize()?.parent() {
Some(sunrise_absolute_base) => {
let image = timetable.get_absolute_image_path(&sunrise_absolute_base);
println!("{}", image.to_str().unwrap());
}
None => {
println!("Failed");
}
},
let now = Local::now();
let sec = now.hour() * 3600 + now.minute() * 60 + now.second();
match sunrise.closest_passed_time(sec) {
Some(timetable) => match cli.file.canonicalize()?.parent() {
Some(sunrise_absolute_base) => {
let image = timetable.get_absolute_image_path(&sunrise_absolute_base);
println!("{}", image.to_str().unwrap());
None => {
println!("Failed");
}
}
None => {
println!("Failed");
}
},
}
None => {
println!("Failed");
Commands::NextAt { file } => {
let sunrise = Sunrise::load_from_file(&file)?;
let now = Local::now();
let sec = now.hour() * 3600 + now.minute() * 60 + now.second();
match sunrise.next_time(sec) {
Some(timetable) => {
println!("{}", sec_to_readable(timetable.time));
}
None => {
println!("Failed");
}
}
}
Commands::NextIn { file, seconds } => {
let sunrise = Sunrise::load_from_file(&file)?;
let now = Local::now();
let sec = now.hour() * 3600 + now.minute() * 60 + now.second();
match sunrise.next_time(sec) {
Some(timetable) => {
let next_in = if timetable.time >= sec {
timetable.time - sec
}else{
timetable.time + (24 * 60 * 60) - sec
};
if seconds {
println!("{}",next_in);
}else{
println!("{}",sec_to_readable(next_in));
}
}
None => {
println!("Failed");
}
}
}
}

View File

@ -16,8 +16,8 @@ pub struct Sunrise {
pub struct Timetable {
/// Time of day in seconds from 0:00
#[serde(deserialize_with = "deserialize_seconds")]
time: u32,
image: PathBuf,
pub time: u32,
pub image: PathBuf,
}
impl Sunrise {
@ -47,6 +47,24 @@ impl Sunrise {
return None; // Return None if the times array is empty
}
}
pub fn next_time(&self, current: u32) -> Option<&Timetable> {
let idx = match self
.schedule
.binary_search_by_key(&current, |time| time.time)
{
Ok(idx) => idx + 1,
Err(idx) => idx,
};
if idx < self.schedule.len() {
Some(&self.schedule[idx])
} else if !self.schedule.is_empty() {
Some(&self.schedule[0]) // Wrap around to the first time
} else {
None // Return None if the times array is empty
}
}
}
impl Timetable {