use clap::Subcommand;
use conciliator::{
Claw,
Conciliator
};
use greg::{
Point,
Calendar
};
use greg_tz::ZONES;
use crate::Nunc;
use crate::core::Zone;
use crate::data::zone::List;
use crate::error::Result;
use super::super::arg;
#[derive(Subcommand)]
pub(crate) enum Cmd {
List,
Current,
Change {
zone_name: String,
when: Option<arg::TimeArg>,
}
}
impl Cmd {
pub(crate) fn run(self, con: &Claw, nunc: &Nunc) -> Result<()> {
match self {
Self::List => cmd_list(con, nunc),
Self::Current => cmd_current(con, nunc),
Self::Change {zone_name, when} =>
cmd_change(con, nunc, zone_name, when)
}
}
}
pub(crate) fn cmd_list(con: &Claw, nunc: &Nunc) -> Result<()> {
let zones = nunc.list()?;
con.print(List::new(&zones));
Ok(())
}
pub(crate) fn cmd_current(con: &Claw, nunc: &Nunc) -> Result<()> {
match List::new(&nunc.list()?).current() {
Some(current) => con.status(current),
None => con.error("No time zone recorded!")
};
Ok(())
}
pub(crate) fn cmd_change(
con: &Claw,
nunc: &Nunc,
zone_name: String,
when: Option<arg::TimeArg>)
-> Result<()>
{
let zone = match ZONES.get(&zone_name) {
Some(&zone) => zone,
None => ret_errmsg!("Time zone {zone_name:?} not found!")
};
let when = match when {
Some(time_arg) => {
let point = time_arg.resolve_with(&Calendar(zone));
con.status("Parsed time in new zone: ")
.push(zone.format_with_name(point));
let table = nunc.load_zone_table()?;
let off = table.offset_at(point);
con.info("Which was/will be: ")
.push(Calendar(off).lookup(point))
.push(' ')
.push(off.name());
point
},
None => Point::now()
};
let question = format!(
"Change time zone to {} at {}?",
zone.name(),
zone.format_with_name(when)
);
match con.confirm(false, &question) {
true if nunc.change(when, zone)? => con.status("Time zone changed!"),
true => ret_errmsg!("Failed to change time zone!"),
false => con.info("Time zone change aborted")
};
Ok(())
}