aboutsummaryrefslogtreecommitdiff
path: root/mling/src/cli/list.rs
blob: 3ae9ef62f3d8a803ef7fc7f796b25f7e9c99926a (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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use colored::Colorize;
use mingling::{
    Groupped, RenderResult, ShellContext, Suggest,
    macros::{chain, completion, dispatcher, pack, r_println, renderer, suggest},
    parser::Picker,
};
use serde::Serialize;

use crate::namespace_manager::list_namespaces;

dispatcher!("ls-namespace", ListInstalledCommand => ListInstalledEntry);

#[completion(ListInstalledEntry)]
pub(crate) fn comp_list_installed(ctx: &ShellContext) -> Suggest {
    if ctx.typing_argument() {
        return suggest! {
            "--trusted": "Show only trusted namespaces",
            "--untrusted": "Show only untrusted namespaces",
        };
    }
    return suggest!();
}

#[derive(Debug, Serialize, Default, Groupped)]
pub(crate) enum StateListInstalledOptions {
    #[default]
    All,
    OnlyTrusted,
    OnlyUntrusted,
}

pack!(MutexErrorListInstalled = ());

#[chain]
pub(crate) fn handle_list_installed_entry(prev: ListInstalledEntry) -> Next {
    let picker = Picker::new(prev.inner);
    let r = picker
        .pick::<bool>("--trusted")
        .pick::<bool>("--untrusted")
        .unpack();

    let option: StateListInstalledOptions = match r {
        // (show_trusted, show_untrusted)
        (true, false) => StateListInstalledOptions::OnlyTrusted,
        (false, true) => StateListInstalledOptions::OnlyUntrusted,
        (false, false) => StateListInstalledOptions::All,
        (true, true) => return MutexErrorListInstalled::default().to_render(),
    };

    option.to_chain()
}

#[renderer]
pub(crate) fn render_list_installed_mutex_error(_prev: MutexErrorListInstalled) {
    r_println!("Error: cannot use both --trusted and --untrusted options at the same time")
}

#[derive(Debug, Groupped, Serialize)]
pub(crate) struct ResultInstalledNamespaces {
    trusted: Vec<String>,
    untrusted: Vec<String>,
    untagged: Vec<String>,
    option: StateListInstalledOptions,
}

#[chain]
pub(crate) fn handle_state_list_installed_option(prev: StateListInstalledOptions) -> Next {
    ResultInstalledNamespaces {
        trusted: list_namespaces(true, false, false),
        untrusted: list_namespaces(false, true, false),
        untagged: list_namespaces(false, false, true),
        option: prev,
    }
}

#[renderer]
pub(crate) fn render_installed(prev: ResultInstalledNamespaces) {
    match prev.option {
        StateListInstalledOptions::All => {
            print_list("Trusted".bright_green().bold().to_string(), prev.trusted, r);
            print_list(
                "Untrusted".bright_red().bold().to_string(),
                prev.untrusted,
                r,
            );
            print_list(
                "Untagged".bright_black().bold().to_string(),
                prev.untagged,
                r,
            );
        }
        StateListInstalledOptions::OnlyTrusted => {
            print_list("Trusted".bright_green().bold().to_string(), prev.trusted, r);
        }
        StateListInstalledOptions::OnlyUntrusted => {
            print_list(
                "Untrusted".bright_red().bold().to_string(),
                prev.untrusted,
                r,
            );
        }
    }
}

fn print_list(title: String, list: Vec<String>, r: &mut RenderResult) {
    if list.is_empty() {
        return;
    }

    r_println!("{}", title);

    for (i, namespace) in (1..).zip(list.iter()) {
        r_println!("  {}. {}", i.to_string(), namespace.bold());
    }
}