1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//! A command line working timer `20min` (twenty-minutes).
//!
//! # Examples
//!
//! ```zsh
//! % 20min 15,5
//! % 20min 0.5 5
//! ```
extern crate structopt;

use std::process::exit;

use structopt::StructOpt;

use twenty_minutes::{config::Config, ticker::tick, split_arg, report};

/// Command line options.
#[derive(Debug, StructOpt)]
#[structopt(
    name = "20min",
    about = "\nA command line working timer. Run with arguments `15,5` \
             (minutes) or OPTIONS \nlike `--work 15 --rest 15`."
)]
struct Opts {
    /// Working time
    #[structopt(short = "w", long = "work", default_value = "15")]
    work: String,

    /// Time of rest
    #[structopt(short = "r", long = "rest", default_value = "5")]
    rest: String,
}

fn main() {
    let mut args: Vec<String> = std::env::args().skip(1).collect();

    // detect argument type ("20,3" or "--work 5 --rest 0.1")
    let mut use_opts: bool = false;
    let o = [
        "-w",
        "--work",
        "-r",
        "--rest",
        "-h",
        "--help",
        "-V",
        "--version",
    ];
    for (_, opt) in o.iter().enumerate() {
        if args.contains(&(opt.to_string())) {
            use_opts = true;
            break;
        }
    }

    if use_opts {
        let opts = Opts::from_args();
        args = vec![opts.work, opts.rest];
    }

    if args.len() == 1 {
        // handle single string input like: "15,5"
        if let Some(v) = split_arg(&args[0]) {
            args = v;
        }
    }

    let c = Config::new(args);
    if c.params.len() > 2 {
        eprintln!("Usage: 20min n (working time) n (time for rest)");
        exit(1);
    }

    let (work_t, rest_t) = c.to_tuple();

    tick(work_t, "Working");
    report(work_t);

    tick(rest_t, "Resting");
    report(rest_t);
}