use chrono::prelude::*;
const PARSING_ERROR: &str = "Invalid time. Use format [hh:mm].";
const SECONDS_PER_DAY: u32 = 24 * 60 * 60;
pub struct Time {
pub hours: u8,
pub minutes: u8,
}
impl Time {
pub fn from(time: &str) -> Result<Time, String> {
let parts: Vec<&str> = time.split(":").collect();
if parts.len() != 2 {
return Err(String::from(PARSING_ERROR))
}
let hours = parse_u8(parts[0])?;
let minutes = parse_u8(parts[1])?;
let bounds_hours = hours < 24;
let bounds_minutes = minutes < 60;
if !bounds_hours || !bounds_minutes {
return Err(String::from(PARSING_ERROR))
}
let time = Time {
hours,
minutes,
};
Ok(time)
}
pub fn current() -> Time {
let local: DateTime<Local> = Local::now();
Time {hours: local.hour() as u8, minutes: local.minute() as u8}
}
pub fn secs(&self) -> u32 {
(self.hours as u32 * 60 + self.minutes as u32) * 60
}
pub fn percent(&self) -> f32 {
self.secs() as f32 / SECONDS_PER_DAY as f32
}
pub fn percent_str(&self) -> String {
let percent = self.percent() * 100.0;
format!("{:.2}%", percent)
}
}
fn parse_u8(num: &str) -> Result<u8, String> {
if let Ok(num) = num.parse::<u8>() {
Ok(num)
} else {
Err(String::from(PARSING_ERROR))
}
}