Skip to main content

safe_chains/registry/
types.rs

1use serde::Deserialize;
2
3use crate::policy::FlagStyle;
4use crate::verdict::SafetyLevel;
5
6#[derive(Debug, Deserialize)]
7pub(super) struct TomlFile {
8    pub command: Vec<TomlCommand>,
9}
10
11#[derive(Debug, Deserialize)]
12pub(super) struct TomlCommand {
13    pub name: String,
14    #[serde(default)]
15    pub aliases: Vec<String>,
16    #[serde(default)]
17    pub url: String,
18    #[serde(default)]
19    pub level: Option<TomlLevel>,
20    #[serde(default)]
21    pub bare: Option<bool>,
22    #[serde(default)]
23    pub max_positional: Option<usize>,
24    #[serde(default)]
25    pub positional_style: Option<bool>,
26    #[serde(default)]
27    pub standalone: Vec<String>,
28    #[serde(default)]
29    pub valued: Vec<String>,
30    #[serde(default)]
31    pub bare_flags: Vec<String>,
32    #[serde(default)]
33    pub sub: Vec<TomlSub>,
34    #[serde(default)]
35    pub handler: Option<String>,
36    #[serde(default)]
37    pub require_any: Vec<String>,
38    #[serde(default)]
39    pub first_arg: Vec<String>,
40    #[serde(default)]
41    pub wrapper: Option<TomlWrapper>,
42    #[allow(dead_code)]
43    #[serde(default)]
44    pub doc: Option<String>,
45}
46
47#[derive(Debug, Deserialize)]
48pub(super) struct TomlWrapper {
49    #[serde(default)]
50    pub standalone: Vec<String>,
51    #[serde(default)]
52    pub valued: Vec<String>,
53    #[serde(default)]
54    pub positional_skip: Option<usize>,
55    #[serde(default)]
56    pub separator: Option<String>,
57    #[serde(default)]
58    pub bare_ok: Option<bool>,
59}
60
61#[derive(Debug, Deserialize)]
62pub(super) struct TomlSub {
63    pub name: String,
64    #[serde(default)]
65    pub level: Option<TomlLevel>,
66    #[serde(default)]
67    pub bare: Option<bool>,
68    #[serde(default)]
69    pub max_positional: Option<usize>,
70    #[serde(default)]
71    pub positional_style: Option<bool>,
72    #[serde(default)]
73    pub standalone: Vec<String>,
74    #[serde(default)]
75    pub valued: Vec<String>,
76    #[serde(default)]
77    pub guard: Option<String>,
78    #[serde(default)]
79    pub guard_short: Option<String>,
80    #[serde(default)]
81    pub allow_all: Option<bool>,
82    #[serde(default)]
83    pub sub: Vec<TomlSub>,
84    #[serde(default)]
85    pub nested_bare: Option<bool>,
86    #[serde(default)]
87    pub require_any: Vec<String>,
88    #[serde(default)]
89    pub first_arg: Vec<String>,
90    #[serde(default)]
91    pub write_flags: Vec<String>,
92    #[serde(default)]
93    pub delegate_after: Option<String>,
94    #[serde(default)]
95    pub delegate_skip: Option<usize>,
96    #[serde(default)]
97    pub handler: Option<String>,
98    #[allow(dead_code)]
99    #[serde(default)]
100    pub doc: Option<String>,
101}
102
103#[derive(Debug, Clone, Copy, Deserialize)]
104pub(super) enum TomlLevel {
105    Inert,
106    SafeRead,
107    SafeWrite,
108}
109
110impl From<TomlLevel> for SafetyLevel {
111    fn from(l: TomlLevel) -> Self {
112        match l {
113            TomlLevel::Inert => SafetyLevel::Inert,
114            TomlLevel::SafeRead => SafetyLevel::SafeRead,
115            TomlLevel::SafeWrite => SafetyLevel::SafeWrite,
116        }
117    }
118}
119
120#[derive(Debug)]
121pub struct CommandSpec {
122    pub name: String,
123    pub aliases: Vec<String>,
124    pub url: String,
125    pub(super) kind: CommandKind,
126}
127
128#[derive(Debug)]
129pub(super) enum CommandKind {
130    Flat {
131        policy: OwnedPolicy,
132        level: SafetyLevel,
133    },
134    FlatRequireAny {
135        require_any: Vec<String>,
136        policy: OwnedPolicy,
137        level: SafetyLevel,
138    },
139    FlatFirstArg {
140        patterns: Vec<String>,
141        level: SafetyLevel,
142    },
143    Structured {
144        bare_flags: Vec<String>,
145        subs: Vec<SubSpec>,
146    },
147    Wrapper {
148        standalone: Vec<String>,
149        valued: Vec<String>,
150        positional_skip: usize,
151        separator: Option<String>,
152        bare_ok: bool,
153    },
154    Custom {
155        #[allow(dead_code)]
156        handler_name: String,
157    },
158}
159
160#[derive(Debug)]
161pub(super) struct SubSpec {
162    pub name: String,
163    pub kind: SubKind,
164}
165
166#[derive(Debug)]
167pub(super) enum SubKind {
168    Policy {
169        policy: OwnedPolicy,
170        level: SafetyLevel,
171    },
172    Guarded {
173        guard_long: String,
174        guard_short: Option<String>,
175        policy: OwnedPolicy,
176        level: SafetyLevel,
177    },
178    Nested {
179        subs: Vec<SubSpec>,
180        allow_bare: bool,
181    },
182    AllowAll {
183        level: SafetyLevel,
184    },
185    WriteFlagged {
186        policy: OwnedPolicy,
187        base_level: SafetyLevel,
188        write_flags: Vec<String>,
189    },
190    FirstArgFilter {
191        patterns: Vec<String>,
192        level: SafetyLevel,
193    },
194    RequireAny {
195        require_any: Vec<String>,
196        policy: OwnedPolicy,
197        level: SafetyLevel,
198    },
199    DelegateAfterSeparator {
200        separator: String,
201    },
202    DelegateSkip {
203        skip: usize,
204        #[allow(dead_code)]
205        doc: String,
206    },
207    Custom {
208        #[allow(dead_code)]
209        handler_name: String,
210    },
211}
212
213#[derive(Debug)]
214pub struct OwnedPolicy {
215    pub standalone: Vec<String>,
216    pub valued: Vec<String>,
217    pub bare: bool,
218    pub max_positional: Option<usize>,
219    pub flag_style: FlagStyle,
220}