aboutsummaryrefslogtreecommitdiff
path: root/src/command.rs
blob: afc00ba5700551cd0ae2483155696ed1480fc156 (plain)
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
use cursive::view::Resizable;
use cursive::views::{Dialog, EditView};
use cursive::Cursive;

use crate::app::App;

pub fn open_command_window(s: &mut Cursive) {
    let command_window = Dialog::around(EditView::new().on_submit(call_on_app).fixed_width(40));
    s.add_layer(command_window);
}

fn call_on_app(s: &mut Cursive, input: &str) {
    s.call_on_name("Main", |view: &mut App| {
        view.parse_command(input);
    });

    // special command that requires access to
    // our main cursive object, has to be parsed again
    // here
    // TODO: fix this somehow
    if Command::from_string(input) == Command::Quit {
        s.quit();
    }

    s.pop_layer();
}

#[derive(PartialEq)]
pub enum Command {
    Add(String, String, Option<u32>), // habit name, habit type, optional goal
    MonthPrev,
    MonthNext,
    Delete(String),
    Quit,
    Blank,
}

impl Command {
    pub fn from_string<P: AsRef<str>>(input: P) -> Self {
        let mut strings: Vec<&str> = input.as_ref().trim().split(' ').collect();
        if strings.is_empty() {
            return Command::Blank;
        }

        let first = strings.first().unwrap().to_string();
        let mut args: Vec<String> = strings.iter_mut().skip(1).map(|s| s.to_string()).collect();
        match first.as_ref() {
            "add" | "a" => {
                if args.len() < 2 {
                    return Command::Blank;
                }
                let goal = args.get(2).map(|g| g.parse::<u32>().ok()).flatten();
                return Command::Add(
                    args.get_mut(0).unwrap().to_string(),
                    args.get_mut(1).unwrap().to_string(),
                    goal,
                );
            }
            "delete" | "d" => {
                if args.len() < 1 {
                    return Command::Blank;
                }
                return Command::Delete(args[0].to_string());
            }
            "mprev" | "month-prev" => return Command::MonthPrev,
            "mnext" | "month-next" => return Command::MonthNext,
            "q" | "quit" => return Command::Quit,
            _ => return Command::Blank,
        }
    }
}