skedge 0.3.0

Ergonomic single-process job scheduling for Rust programs.
Documentation
// Some more varied usage examples.

use jiff::{ToSpan, Zoned};
use skedge::{every, every_single, Scheduler};
use std::thread::sleep;
use std::time::Duration;

fn job() {
	let now = Zoned::now();
	println!("Hello, it's {now}!");
}

fn flirt(name: &str, time: &str, hour: u8, jackpot: i32, restaurant: &str, meal: &str) {
	println!(
		"Hello, {name}!  What are you doing {time}?  I'm free around {hour}.  \
        I just won ${jackpot} off a scratch ticket, you can get anything you want.  \
        Have you ever been to {restaurant}?  They're getting rave reviews over their {meal}."
	);
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
	let mut schedule = Scheduler::new();

	every(10).seconds()?.run(&mut schedule, job)?;

	every(10).minutes()?.run(&mut schedule, job)?;

	every_single().hour()?.run(&mut schedule, job)?;

	every_single().day()?.at("10:30")?.run(&mut schedule, job)?;

	every(5).to(10)?.minutes()?.run(&mut schedule, job)?;

	every_single().monday()?.run(&mut schedule, job)?;

	every_single()
		.wednesday()?
		.at("13:15")?
		.run(&mut schedule, job)?;

	every(2)
		.to(8)?
		.seconds()?
		.until(Zoned::now().checked_add(5.seconds()).unwrap())?
		.run_six_args(
			&mut schedule,
			flirt,
			"Cool Person",
			"Friday",
			7,
			40,
			"Dorsia",
			"foraged chanterelle croque monsieur",
		)?;

	let now = Zoned::now();
	println!("Starting at {now}");
	loop {
		if let Err(e) = schedule.run_pending() {
			eprintln!("Error: {e}");
		}
		sleep(Duration::from_secs(1));
	}
}