improve debuggability
more Debug-derives, trace/verbose, …
This commit is contained in:
parent
4686eff0d4
commit
12501c8c73
|
@ -10,6 +10,7 @@ use std::collections::BTreeSet;
|
|||
use std::error::Error;
|
||||
|
||||
/// Defines a day within the month. Negative numbers count from the end.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum DaySpec {
|
||||
/// nth day, no matter the weekday
|
||||
DayOfMonth(i32),
|
||||
|
|
115
src/main.rs
115
src/main.rs
|
@ -141,20 +141,67 @@ macro_rules! verboseln {
|
|||
fn is_trace() -> bool {
|
||||
env::var("TRACE").map(|v| !v.is_empty()).unwrap_or(false)
|
||||
}
|
||||
/// Like `println!`, but only if `is_trace` is true (due to the environment
|
||||
/// variable `TRACE` being set.)
|
||||
macro_rules! traceln {
|
||||
($($arg:tt)*) => {
|
||||
if is_trace() {
|
||||
println!($($arg)*);
|
||||
println!( "{}", format!($($arg)*).yellow() );
|
||||
}
|
||||
};
|
||||
}
|
||||
/// `trace_var!( [msg,] var )` prints either `varname = value` or `msg: value`
|
||||
/// *if TRACE is set* (else is silent.)
|
||||
///
|
||||
/// There's an alternative form of `trace_var!( [msg,] var[, true] )` or the
|
||||
/// preferred form of `trace_var_!( [msg,] var )` (i.e. just add an underscore
|
||||
/// to the name), which will use the "pretty" form.
|
||||
macro_rules! trace_var {
|
||||
($var:expr, $pretty:expr) => {
|
||||
if is_trace() {
|
||||
if $pretty {
|
||||
println!("{} = {}", stringify!($var).green(), format!("{:#?}", $var).cyan());
|
||||
} else {
|
||||
println!("{} = {}", stringify!($var).green(), format!("{:?}", $var).cyan());
|
||||
}
|
||||
}
|
||||
};
|
||||
($msg:expr, $var:expr, $pretty:expr) => {
|
||||
if is_trace() {
|
||||
if $pretty {
|
||||
println!("{}: {}", $msg.green(), format!("{:#?}", $var).cyan());
|
||||
} else {
|
||||
println!("{}: {}", $msg.green(), format!("{:?}", $var).cyan());
|
||||
}
|
||||
}
|
||||
};
|
||||
($var:expr) => {
|
||||
trace_var!($var, false);
|
||||
};
|
||||
($msg:expr, $var:expr) => {
|
||||
trace_var!($msg, $var, false);
|
||||
};
|
||||
}
|
||||
|
||||
/// Pretty form of `trace_var!`
|
||||
macro_rules! trace_var_ {
|
||||
($var:expr) => {
|
||||
trace_var!($var, true);
|
||||
};
|
||||
($msg:expr, $var:expr) => {
|
||||
trace_var!($msg, $var, true);
|
||||
};
|
||||
}
|
||||
|
||||
/// Gets either today or the date from the environment variable `TODAY` (for
|
||||
/// testing purposes.)
|
||||
fn today() -> NaiveDate {
|
||||
env::var("TODAY")
|
||||
.map(|v| NaiveDate::parse_from_str(&v, "%F").expect("'TODAY' hat nicht format YYYY-MM-DD"))
|
||||
.unwrap_or(Local::now().date_naive())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Args {
|
||||
check_mode: bool,
|
||||
config_file: String,
|
||||
|
@ -190,8 +237,9 @@ fn parse_args() -> Args {
|
|||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
// set up config file access
|
||||
let args = parse_args();
|
||||
trace_var!(args);
|
||||
let config_file = args.config_file.as_str();
|
||||
verboseln!("Using config file {config_file}.");
|
||||
verboseln!("Using config file {}.", config_file.cyan());
|
||||
let config = KV::new(config_file).unwrap();
|
||||
config_spec::populate_defaults(&CONFIG_SPEC, &config);
|
||||
if args.check_mode {
|
||||
|
@ -200,7 +248,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
}
|
||||
// get config
|
||||
let hedgedoc = HedgeDoc::new(&config["hedgedoc-server-url"], is_dry_run());
|
||||
traceln!("Hedgedoc: {:?}", hedgedoc);
|
||||
trace_var!(hedgedoc);
|
||||
let email_ = Email::new(
|
||||
&config["email-server"],
|
||||
&config["email-user"],
|
||||
|
@ -213,18 +261,21 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
&config["email-to"],
|
||||
config.get("email-in-reply-to").ok(),
|
||||
);
|
||||
traceln!("Email: {:?}", email);
|
||||
trace_var_!(email);
|
||||
let wiki = Mediawiki::new(
|
||||
&config["wiki-server-url"],
|
||||
&config["wiki-http-user"],
|
||||
&config["wiki-http-password"],
|
||||
is_dry_run(),
|
||||
);
|
||||
traceln!("Wiki: {:?}", wiki);
|
||||
trace_var_!(wiki);
|
||||
// get next plenum days
|
||||
let today = today();
|
||||
verboseln!("Heute ist {}", today.to_string().cyan());
|
||||
let plenum_spec = date::parse_spec(&config["date-spec"])?;
|
||||
trace_var!(plenum_spec);
|
||||
let nearest_plenum_days = date::get_matching_dates_around(today, plenum_spec);
|
||||
trace_var!(nearest_plenum_days);
|
||||
// figure out where we are
|
||||
let mut last_state = ProgramState::parse(&config["state-name"]);
|
||||
let last_run = config.get("state-last-run").unwrap_or_default();
|
||||
|
@ -256,20 +307,28 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
}
|
||||
.unwrap(); // always has at least 2 elems
|
||||
let plenum_day = today.checked_add_signed(chrono::TimeDelta::days(delta)).unwrap();
|
||||
verboseln!(
|
||||
"Relevantes Plenum ist am {} ({})",
|
||||
plenum_day.to_string().cyan(),
|
||||
relative_date(delta).cyan()
|
||||
);
|
||||
let intended_state = if delta > 3 {
|
||||
ProgramState::Normal // nothing to do 3+ days in advance
|
||||
} else if delta > 1 {
|
||||
ProgramState::Announced // 2+ days in advance we want to have it announced
|
||||
} else if delta >= 0 {
|
||||
ProgramState::Reminded // up to the day of, we want to send a reminder (or cancel)
|
||||
} else if delta > -2 {
|
||||
} else if delta >= -1 {
|
||||
ProgramState::Waiting // we will wait a day for the protocol to be cleaned up
|
||||
} else {
|
||||
ProgramState::Logged // after that, we want to log it to the list & the wiki
|
||||
};
|
||||
verboseln!("Aktueller Zustand: {}", last_state.to_string().cyan());
|
||||
verboseln!("Soll-Zustand: {}", intended_state.to_string().cyan());
|
||||
|
||||
let action: TransitionFunction = TRANSITION_LUT[last_state as usize][intended_state as usize];
|
||||
action(delta, &plenum_day, &config, &hedgedoc, &email, &wiki)?;
|
||||
let action: &ST = &TRANSITION_LUT[last_state as usize][intended_state as usize];
|
||||
trace_var!(action);
|
||||
action.get()(delta, &plenum_day, &config, &hedgedoc, &email, &wiki)?;
|
||||
|
||||
// TODO: cleanup / write new state
|
||||
|
||||
|
@ -638,15 +697,41 @@ type TransitionFunction = fn(
|
|||
) -> Result<(), Box<dyn Error>>;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const TRANSITION_LUT: [[TransitionFunction; 5]; 5] = [
|
||||
/* NORMAL ANNOUNCED REMINDED WAITING LOGGED */
|
||||
/* NORMAL */ [nop, do_announcement, do_reminder, nop, nop],
|
||||
/* ANNOUNCED */ [do_cleanup, nop, do_reminder, nop, do_protocol],
|
||||
/* REMINDED */ [do_cleanup, do_clean_announcement, nop, nop, do_protocol],
|
||||
/* WAITING */ [do_cleanup, do_clean_announcement, do_clean_reminder, nop, do_protocol],
|
||||
/* LOGGED */ [do_cleanup, do_clean_announcement, do_clean_reminder, nop, do_cleanup],
|
||||
const TRANSITION_LUT: [[ST; 5]; 5] = [
|
||||
/* NORMAL ANNOUNCED REMINDED WAITING LOGGED */
|
||||
/* NORMAL */ [ST::Nop, ST::DoAnnouncement, ST::DoReminder, ST::Nop, ST::Nop],
|
||||
/* ANNOUNCED */ [ST::DoCleanup, ST::Nop, ST::DoReminder, ST::Nop, ST::DoProtocol],
|
||||
/* REMINDED */ [ST::DoCleanup, ST::DoCleanupThenAnnouncement, ST::Nop, ST::Nop, ST::DoProtocol],
|
||||
/* WAITING */ [ST::DoCleanup, ST::DoCleanupThenAnnouncement, ST::DoCleanupThenReminder, ST::Nop, ST::DoProtocol],
|
||||
/* LOGGED */ [ST::DoCleanup, ST::DoCleanupThenAnnouncement, ST::DoCleanupThenReminder, ST::Nop, ST::DoCleanup],
|
||||
];
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy)]
|
||||
enum ST {
|
||||
#[default]
|
||||
Nop,
|
||||
DoAnnouncement,
|
||||
DoReminder,
|
||||
DoProtocol,
|
||||
DoCleanup,
|
||||
DoCleanupThenAnnouncement,
|
||||
DoCleanupThenReminder,
|
||||
}
|
||||
|
||||
impl ST {
|
||||
fn get(&self) -> TransitionFunction {
|
||||
match self {
|
||||
ST::Nop => nop,
|
||||
ST::DoAnnouncement => do_announcement,
|
||||
ST::DoReminder => do_reminder,
|
||||
ST::DoProtocol => do_protocol,
|
||||
ST::DoCleanup => do_cleanup,
|
||||
ST::DoCleanupThenAnnouncement => do_clean_announcement,
|
||||
ST::DoCleanupThenReminder => do_clean_reminder,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn nop(
|
||||
_: i64, _: &NaiveDate, _: &KV, _: &HedgeDoc, _: &SimpleEmail, _: &Mediawiki,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
|
|
|
@ -35,7 +35,6 @@ pub const CONFIG: CfgGroup<'static> = CfgGroup {
|
|||
],
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Mediawiki {
|
||||
server_url: String,
|
||||
http_user: String,
|
||||
|
@ -44,6 +43,18 @@ pub struct Mediawiki {
|
|||
client: Client,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Mediawiki {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Mediawiki")
|
||||
.field("server_url", &self.server_url)
|
||||
.field("http_user", &self.http_user)
|
||||
.field("http_password", &"*****")
|
||||
.field("is_dry_run", &self.is_dry_run)
|
||||
.field("client", &self.client)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Mediawiki {
|
||||
pub fn new(
|
||||
server_url: &str, http_auth_user: &str, http_auth_password: &str, is_dry_run: bool,
|
||||
|
|
Loading…
Reference in a new issue