jobber 0.1.2-alpha

Minimalistic console work time tracker
use std::str::FromStr;

use inquire::{Select, Text, validator::Validation};

use crate::{
    commands::edit::{map_empty, obligatory},
    entities::{Rate, Scheme, WorkingInterval},
};

pub(crate) fn edit_scheme(scheme: &mut Scheme) -> crate::database::Result<bool> {
    let orig = scheme.clone();

    println!();
    println!("Enter a working scheme...");
    println!();
    scheme.rate = map_empty(
        Text::new("Payment Rate?")
            .with_default(
                &orig
                    .rate
                    .clone()
                    .map(|r| r.to_string())
                    .unwrap_or("-".into()),
            )
            .with_help_message("e.g. $50/h, 50EUR/30min (enter '-' to remove)")
            .with_validator(|input: &str| match (Rate::from_str(input), input) {
                (Ok(_), _) | (Err(_), "-") => Ok(Validation::Valid),
                (Err(_), _) => Ok(Validation::Invalid("invalid format".into())),
            })
            .prompt()?,
    )
    .map(|r| r.parse())
    .transpose()?;
    scheme.billing_period = map_empty(
        Select::new(
            "Billing Period?",
            vec!["-", "daily", "weekly", "every2weeks", "monthly"],
        )
        .with_starting_filter_input(
            &orig
                .billing_period
                .map(|r| r.to_string())
                .unwrap_or("-".into()),
        )
        .with_help_message("you will get reminded of pending bills (select '-' to remove)")
        .prompt()?
        .to_string(),
    )
    .map(|r| r.parse())
    .transpose()?;

    scheme.min_work_interval = Text::new("Minimum Working Interval?")
        .with_default(&orig.min_work_interval.to_string())
        .with_help_message("this will be the \"time grid\" of you work")
        .with_validators(&[
            Box::new(obligatory),
            Box::new(|input: &str| match WorkingInterval::from_str(input) {
                Ok(_) => Ok(Validation::Valid),
                Err(_) => Ok(Validation::Invalid("invalid format".into())),
            }),
        ])
        .prompt()?
        .parse()?;

    Ok(orig != *scheme)
}