mask_parser/
maskfile.rs

1use serde::Serialize;
2use serde_json::Value;
3
4#[derive(Debug, Serialize, Clone)]
5pub struct Maskfile {
6    pub title: String,
7    pub description: String,
8    pub commands: Vec<Command>,
9}
10
11impl Maskfile {
12    pub fn to_json(&self) -> Result<Value, serde_json::Error> {
13        serde_json::to_value(&self)
14    }
15}
16
17#[derive(Debug, Serialize, Clone)]
18pub struct Command {
19    pub level: u8,
20    pub name: String,
21    pub description: String,
22    pub script: Option<Script>,
23    pub subcommands: Vec<Command>,
24    pub required_args: Vec<RequiredArg>,
25    pub optional_args: Vec<OptionalArg>,
26    pub named_flags: Vec<NamedFlag>,
27}
28
29impl Command {
30    pub fn new(level: u8) -> Self {
31        Self {
32            level,
33            name: "".to_string(),
34            description: "".to_string(),
35            script: Some(Script::new()),
36            subcommands: vec![],
37            required_args: vec![],
38            optional_args: vec![],
39            named_flags: vec![],
40        }
41    }
42
43    pub fn build(mut self) -> Self {
44        // Set to None if there is no source and executor
45        if let Some(s) = &mut self.script {
46            if s.source.is_empty() && s.executor.is_empty() {
47                self.script = None;
48            }
49        }
50
51        // Auto add common flags like verbose for commands that have a script source
52        if self.script.is_some() {
53            self.named_flags.push(NamedFlag {
54                name: "verbose".to_string(),
55                description: "Sets the level of verbosity".to_string(),
56                short: "v".to_string(),
57                long: "verbose".to_string(),
58                multiple: false,
59                takes_value: false,
60                required: false,
61                validate_as_number: false,
62                choices: vec![],
63                val: "".to_string(),
64            });
65        }
66        self
67    }
68}
69
70#[derive(Debug, Serialize, Clone)]
71pub struct Script {
72    // The executor to run the source with
73    pub executor: String, // shell, node, ruby, python, etc...
74    // The script source to execute
75    pub source: String,
76}
77
78impl Script {
79    pub fn new() -> Self {
80        Self {
81            executor: "".to_string(),
82            source: "".to_string(),
83        }
84    }
85}
86
87#[derive(Debug, Serialize, Clone)]
88pub struct RequiredArg {
89    pub name: String,
90    /// Used within mask. TODO: store in a different place within mask instead of here.
91    #[serde(skip)]
92    pub val: String,
93}
94
95impl RequiredArg {
96    pub fn new(name: String) -> Self {
97        Self {
98            name,
99            val: "".to_string(),
100        }
101    }
102}
103
104#[derive(Debug, Serialize, Clone)]
105pub struct OptionalArg {
106    pub name: String,
107    /// Used within mask. TODO: store in a different place within mask instead of here.
108    #[serde(skip)]
109    pub val: String,
110}
111
112impl OptionalArg {
113    pub fn new(name: String) -> Self {
114        Self {
115            name,
116            val: "".to_string(),
117        }
118    }
119}
120
121#[derive(Debug, Serialize, Clone)]
122pub struct NamedFlag {
123    pub name: String,
124    pub description: String,
125    pub short: String,            // v        (used as -v)
126    pub long: String,             // verbose  (used as --verbose)
127    pub multiple: bool,           // Can it have multiple values? (-vvv OR -i one -i two)
128    pub takes_value: bool,        // Does it take a value? (-i value)
129    pub validate_as_number: bool, // Should we validate it as a number?
130    pub choices: Vec<String>,     // Choices of flag value.
131    pub required: bool,
132    /// Used within mask. TODO: store in a different place within mask instead of here.
133    #[serde(skip)]
134    pub val: String,
135}
136
137impl NamedFlag {
138    pub fn new() -> Self {
139        Self {
140            name: "".to_string(),
141            description: "".to_string(),
142            short: "".to_string(),
143            long: "".to_string(),
144            multiple: false,
145            takes_value: false,
146            required: false,
147            validate_as_number: false,
148            choices: vec![],
149            val: "".to_string(),
150        }
151    }
152}