1use serde::Deserialize;
2
3use crate::verdict::SafetyLevel;
4
5#[derive(Debug, Deserialize)]
6pub(super) struct TomlFile {
7 pub command: Vec<TomlCommand>,
8}
9
10#[derive(Debug, Deserialize)]
11pub(super) struct TomlCommand {
12 pub name: String,
13 #[serde(default)]
14 pub description: Option<String>,
15 #[serde(default)]
16 pub candidate: Option<bool>,
17 #[serde(default)]
18 pub aliases: Vec<String>,
19 #[serde(default)]
20 pub url: String,
21 #[serde(default)]
22 pub level: Option<TomlLevel>,
23 #[serde(default)]
24 pub bare: Option<bool>,
25 #[serde(default)]
26 pub max_positional: Option<usize>,
27 #[serde(default)]
32 pub positional_style: Option<bool>,
33 #[serde(default)]
34 pub tolerate_unknown_short: Option<bool>,
35 #[serde(default)]
36 pub tolerate_unknown_long: Option<bool>,
37 #[serde(default)]
38 pub numeric_dash: Option<bool>,
39 #[serde(default)]
40 pub standalone: Vec<String>,
41 #[serde(default)]
42 pub valued: Vec<String>,
43 #[serde(default)]
44 pub bare_flags: Vec<String>,
45 #[serde(default)]
46 pub sub: Vec<TomlSub>,
47 #[serde(default)]
48 pub handler: Option<String>,
49 #[serde(default)]
50 pub doc_body: Option<String>,
51 #[serde(default)]
52 pub require_any: Vec<String>,
53 #[serde(default)]
54 pub first_arg: Vec<String>,
55 #[serde(default)]
56 pub wrapper: Option<TomlWrapper>,
57 #[serde(default)]
58 pub write_flags: Vec<String>,
59 #[serde(default)]
60 pub researched_version: Option<String>,
61 #[serde(default)]
66 pub examples_safe: Vec<String>,
67 #[serde(default)]
68 pub examples_denied: Vec<String>,
69 #[serde(default)]
73 pub deny: Option<bool>,
74 #[serde(default)]
79 pub fallback: Option<TomlFallback>,
80 #[serde(default)]
86 pub handler_policy: std::collections::HashMap<String, TomlHandlerPolicy>,
87 #[serde(default)]
93 pub matrix: Vec<TomlMatrix>,
94}
95
96#[derive(Debug, Deserialize)]
97pub(super) struct TomlMatrix {
98 pub parents: Vec<String>,
99 pub level: TomlLevel,
100 pub actions: std::collections::HashMap<String, TomlMatrixAction>,
101}
102
103#[derive(Debug, Deserialize)]
104#[serde(untagged)]
105pub(super) enum TomlMatrixAction {
106 Policy(String),
109 Detailed {
113 policy: String,
114 #[serde(default)]
115 guard: Option<String>,
116 #[serde(default)]
117 guard_short: Option<String>,
118 },
119}
120
121#[derive(Debug, Deserialize)]
122pub(super) struct TomlHandlerPolicy {
123 #[serde(default)]
124 pub standalone: Vec<String>,
125 #[serde(default)]
126 pub valued: Vec<String>,
127 #[serde(default)]
128 pub bare: Option<bool>,
129 #[serde(default)]
130 pub max_positional: Option<usize>,
131 #[serde(default)]
132 pub tolerate_unknown_short: Option<bool>,
133 #[serde(default)]
134 pub tolerate_unknown_long: Option<bool>,
135 #[serde(default)]
136 pub numeric_dash: Option<bool>,
137}
138
139#[derive(Debug, Deserialize)]
140pub(super) struct TomlFallback {
141 #[serde(default)]
142 pub level: Option<TomlLevel>,
143 #[serde(default)]
144 pub bare: Option<bool>,
145 #[serde(default)]
146 pub max_positional: Option<usize>,
147 #[serde(default)]
148 pub standalone: Vec<String>,
149 #[serde(default)]
150 pub valued: Vec<String>,
151 #[serde(default)]
152 pub tolerate_unknown_short: Option<bool>,
153 #[serde(default)]
154 pub tolerate_unknown_long: Option<bool>,
155 #[serde(default)]
156 pub numeric_dash: Option<bool>,
157 #[serde(default)]
163 pub positional_shape: Option<String>,
164}
165
166#[derive(Debug, Deserialize)]
167pub(super) struct TomlWrapper {
168 #[serde(default)]
169 pub standalone: Vec<String>,
170 #[serde(default)]
171 pub valued: Vec<String>,
172 #[serde(default)]
173 pub positional_skip: Option<usize>,
174 #[serde(default)]
175 pub separator: Option<String>,
176 #[serde(default)]
177 pub bare_ok: Option<bool>,
178}
179
180#[derive(Debug, Deserialize)]
181pub(super) struct TomlSub {
182 pub name: String,
183 #[serde(default)]
184 pub candidate: Option<bool>,
185 #[serde(default)]
186 pub aliases: Vec<String>,
187 #[serde(default)]
188 pub level: Option<TomlLevel>,
189 #[serde(default)]
190 pub bare: Option<bool>,
191 #[serde(default)]
192 pub max_positional: Option<usize>,
193 #[serde(default)]
195 pub positional_style: Option<bool>,
196 #[serde(default)]
197 pub tolerate_unknown_short: Option<bool>,
198 #[serde(default)]
199 pub tolerate_unknown_long: Option<bool>,
200 #[serde(default)]
201 pub numeric_dash: Option<bool>,
202 #[serde(default)]
203 pub standalone: Vec<String>,
204 #[serde(default)]
205 pub valued: Vec<String>,
206 #[serde(default)]
207 pub guard: Option<String>,
208 #[serde(default)]
209 pub guard_short: Option<String>,
210 #[serde(default)]
211 pub allow_all: Option<bool>,
212 #[serde(default)]
218 pub policy: Option<String>,
219 #[serde(default)]
220 pub sub: Vec<TomlSub>,
221 #[serde(default)]
222 pub nested_bare: Option<bool>,
223 #[serde(default)]
224 pub require_any: Vec<String>,
225 #[serde(default)]
226 pub first_arg: Vec<String>,
227 #[serde(default)]
228 pub write_flags: Vec<String>,
229 #[serde(default)]
230 pub delegate_after: Option<String>,
231 #[serde(default)]
232 pub delegate_skip: Option<usize>,
233 #[serde(default)]
234 pub handler: Option<String>,
235 #[serde(default)]
236 pub doc_body: Option<String>,
237}
238
239#[derive(Debug, Clone, Copy, Deserialize)]
240pub(super) enum TomlLevel {
241 Inert,
242 SafeRead,
243 SafeWrite,
244}
245
246impl From<TomlLevel> for SafetyLevel {
247 fn from(l: TomlLevel) -> Self {
248 match l {
249 TomlLevel::Inert => SafetyLevel::Inert,
250 TomlLevel::SafeRead => SafetyLevel::SafeRead,
251 TomlLevel::SafeWrite => SafetyLevel::SafeWrite,
252 }
253 }
254}
255
256#[derive(Debug)]
257pub struct CommandSpec {
258 pub name: String,
259 pub description: String,
260 pub aliases: Vec<String>,
261 pub url: String,
262 pub category: String,
263 pub researched_version: Option<String>,
270 pub examples_safe: Vec<String>,
273 pub examples_denied: Vec<String>,
277 pub(super) kind: DispatchKind,
278}
279
280#[derive(Debug, Clone)]
281pub(super) struct SubSpec {
282 pub name: String,
283 pub kind: DispatchKind,
284 pub policy_ref: Option<String>,
289}
290
291#[derive(Debug, Clone)]
292pub(super) enum DispatchKind {
293 Policy {
294 policy: OwnedPolicy,
295 level: SafetyLevel,
296 },
297 FirstArg {
298 patterns: Vec<String>,
299 level: SafetyLevel,
300 },
301 RequireAny {
302 require_any: Vec<String>,
303 policy: OwnedPolicy,
304 level: SafetyLevel,
305 accept_bare_help: bool,
306 },
307 Branching {
308 subs: Vec<SubSpec>,
309 bare_flags: Vec<String>,
310 bare_ok: bool,
311 pre_standalone: Vec<String>,
312 pre_valued: Vec<String>,
313 first_arg: Vec<String>,
314 first_arg_level: SafetyLevel,
315 },
316 WriteFlagged {
317 policy: OwnedPolicy,
318 base_level: SafetyLevel,
319 write_flags: Vec<String>,
320 },
321 DelegateAfterSeparator {
322 separator: String,
323 },
324 DelegateSkip {
325 skip: usize,
326 },
327 Wrapper {
328 standalone: Vec<String>,
329 valued: Vec<String>,
330 positional_skip: usize,
331 separator: Option<String>,
332 bare_ok: bool,
333 },
334 Custom {
335 #[allow(dead_code)]
336 handler_name: String,
337 doc_body: Option<String>,
338 subs: Vec<SubSpec>,
342 fallback: Option<FallbackSpec>,
346 handler_policies: std::collections::HashMap<String, OwnedPolicy>,
350 matrices: Vec<MatrixSpec>,
353 },
354}
355
356#[derive(Debug, Clone)]
357pub struct OwnedPolicy {
358 pub standalone: Vec<String>,
359 pub valued: Vec<String>,
360 pub bare: bool,
361 pub max_positional: Option<usize>,
362 pub tolerance: crate::policy::FlagTolerance,
363}
364
365#[derive(Debug, Clone)]
366pub(super) struct MatrixSpec {
367 pub parents: Vec<String>,
368 pub level: SafetyLevel,
369 pub actions: std::collections::HashMap<String, MatrixAction>,
370}
371
372#[derive(Debug, Clone)]
373pub(super) struct MatrixAction {
374 pub policy_key: String,
375 pub guard: Option<String>,
376 pub guard_short: Option<String>,
377}
378
379#[derive(Debug, Clone)]
380pub(super) struct FallbackSpec {
381 pub policy: OwnedPolicy,
382 pub level: SafetyLevel,
383 pub positional_shape: Option<crate::policy::PositionalShape>,
384}