aboutsummaryrefslogtreecommitdiff
path: root/src/cli/ops_cmd.rs
blob: 4b0eea7d734846b754bea94d803f8c34a6f46c61 (plain) (blame)
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
use std::{
    env::current_dir,
    fs::{self, create_dir_all},
    path::PathBuf,
};

use mingling::{
    AnyOutput,
    macros::{chain, dispatcher, pack, r_println, renderer},
    marker::NextProcess,
    parser::Picker,
};

use crate::{
    ThisProgram,
    cli::{consts::BILL_WORKSPACE_CONFIG_FILE, io_error::IOError},
};

dispatcher!("init", InitHereCommand => InitEntry);
dispatcher!("create", CreateCommand => CreateEntry);

pack!(StateCreateWorkspace = PathBuf);

#[chain]
pub async fn handle_init_command(_prev: InitEntry) -> NextProcess {
    let current_dir = match current_dir() {
        Ok(d) => d,
        Err(e) => return AnyOutput::new(IOError::from(e)).route_renderer(),
    };
    StateCreateWorkspace::new(current_dir).to_chain()
}

#[chain]
pub async fn handle_create_command(prev: CreateEntry) -> NextProcess {
    let path = pick_path(prev.inner);
    StateCreateWorkspace::new(path).to_chain()
}

#[chain]
pub async fn handle_state_create_workspace(prev: StateCreateWorkspace) -> NextProcess {
    let dir = prev.inner;
    let file = dir.join(BILL_WORKSPACE_CONFIG_FILE);

    match create_dir_all(&dir) {
        Ok(d) => d,
        Err(e) => return AnyOutput::new(IOError::from(e)).route_renderer(),
    };

    if file.exists() {
        return AnyOutput::new(WorkspaceConfigAlreadyExists::new(dir)).route_renderer();
    }

    if let Err(e) = fs::write(file, "") {
        return AnyOutput::new(IOError::from(e)).route_renderer();
    }

    StateWorkspaceCreated::new(dir).to_render()
}

pack!(StateWorkspaceCreated = PathBuf);

#[renderer]
pub fn render_workspace_created(prev: StateWorkspaceCreated) {
    r_println!("Workspace created at: {:?}", prev.inner);
}

pack!(WorkspaceConfigAlreadyExists = PathBuf);

#[renderer]
pub fn render_workspace_config_already_exists(prev: WorkspaceConfigAlreadyExists) {
    r_println!("Workspace config already exists: {:?}", prev.inner);
}

fn pick_path(args: Vec<String>) -> PathBuf {
    let path = Picker::<()>::new(args)
        .pick::<String>(())
        .unpack_directly()
        .0;
    PathBuf::from(path)
}