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)]
75 pub eval_safe: Option<bool>,
76 #[serde(default)]
81 pub eval_safe_flags: Vec<String>,
82 #[serde(default)]
86 pub deny: Option<bool>,
87 #[serde(default)]
92 pub fallback: Option<TomlFallback>,
93 #[serde(default)]
99 pub handler_policy: std::collections::HashMap<String, TomlHandlerPolicy>,
100 #[serde(default)]
106 pub matrix: Vec<TomlMatrix>,
107}
108
109#[derive(Debug, Deserialize)]
110pub(super) struct TomlMatrix {
111 pub parents: Vec<String>,
112 pub level: TomlLevel,
113 pub actions: std::collections::HashMap<String, TomlMatrixAction>,
114}
115
116#[derive(Debug, Deserialize)]
117#[serde(untagged)]
118pub(super) enum TomlMatrixAction {
119 Policy(String),
122 Detailed {
126 policy: String,
127 #[serde(default)]
128 guard: Option<String>,
129 #[serde(default)]
130 guard_short: Option<String>,
131 },
132}
133
134#[derive(Debug, Deserialize)]
135pub(super) struct TomlHandlerPolicy {
136 #[serde(default)]
137 pub standalone: Vec<String>,
138 #[serde(default)]
139 pub valued: Vec<String>,
140 #[serde(default)]
141 pub bare: Option<bool>,
142 #[serde(default)]
143 pub max_positional: Option<usize>,
144 #[serde(default)]
145 pub tolerate_unknown_short: Option<bool>,
146 #[serde(default)]
147 pub tolerate_unknown_long: Option<bool>,
148 #[serde(default)]
149 pub numeric_dash: Option<bool>,
150}
151
152#[derive(Debug, Deserialize)]
153pub(super) struct TomlFallback {
154 #[serde(default)]
155 pub level: Option<TomlLevel>,
156 #[serde(default)]
157 pub bare: Option<bool>,
158 #[serde(default)]
159 pub max_positional: Option<usize>,
160 #[serde(default)]
161 pub standalone: Vec<String>,
162 #[serde(default)]
163 pub valued: Vec<String>,
164 #[serde(default)]
165 pub tolerate_unknown_short: Option<bool>,
166 #[serde(default)]
167 pub tolerate_unknown_long: Option<bool>,
168 #[serde(default)]
169 pub numeric_dash: Option<bool>,
170 #[serde(default)]
176 pub positional_shape: Option<String>,
177}
178
179#[derive(Debug, Deserialize)]
180pub(super) struct TomlWrapper {
181 #[serde(default)]
182 pub standalone: Vec<String>,
183 #[serde(default)]
184 pub valued: Vec<String>,
185 #[serde(default)]
186 pub positional_skip: Option<usize>,
187 #[serde(default)]
188 pub separator: Option<String>,
189 #[serde(default)]
190 pub bare_ok: Option<bool>,
191}
192
193#[derive(Debug, Deserialize)]
194pub(super) struct TomlSub {
195 pub name: String,
196 #[serde(default)]
197 pub candidate: Option<bool>,
198 #[serde(default)]
199 pub aliases: Vec<String>,
200 #[serde(default)]
201 pub level: Option<TomlLevel>,
202 #[serde(default)]
203 pub bare: Option<bool>,
204 #[serde(default)]
205 pub max_positional: Option<usize>,
206 #[serde(default)]
208 pub positional_style: Option<bool>,
209 #[serde(default)]
210 pub tolerate_unknown_short: Option<bool>,
211 #[serde(default)]
212 pub tolerate_unknown_long: Option<bool>,
213 #[serde(default)]
214 pub numeric_dash: Option<bool>,
215 #[serde(default)]
216 pub standalone: Vec<String>,
217 #[serde(default)]
218 pub valued: Vec<String>,
219 #[serde(default)]
220 pub guard: Option<String>,
221 #[serde(default)]
222 pub guard_short: Option<String>,
223 #[serde(default)]
224 pub allow_all: Option<bool>,
225 #[serde(default)]
231 pub policy: Option<String>,
232 #[serde(default)]
233 pub sub: Vec<TomlSub>,
234 #[serde(default)]
235 pub nested_bare: Option<bool>,
236 #[serde(default)]
237 pub require_any: Vec<String>,
238 #[serde(default)]
239 pub first_arg: Vec<String>,
240 #[serde(default)]
241 pub write_flags: Vec<String>,
242 #[serde(default)]
243 pub delegate_after: Option<String>,
244 #[serde(default)]
245 pub delegate_skip: Option<usize>,
246 #[serde(default)]
247 pub handler: Option<String>,
248 #[serde(default)]
249 pub doc_body: Option<String>,
250 #[serde(default)]
256 pub eval_safe: Option<bool>,
257 #[serde(default)]
262 pub eval_safe_flags: Vec<String>,
263}
264
265#[derive(Debug, Clone, Copy, Deserialize)]
266pub(super) enum TomlLevel {
267 Inert,
268 SafeRead,
269 SafeWrite,
270}
271
272impl From<TomlLevel> for SafetyLevel {
273 fn from(l: TomlLevel) -> Self {
274 match l {
275 TomlLevel::Inert => SafetyLevel::Inert,
276 TomlLevel::SafeRead => SafetyLevel::SafeRead,
277 TomlLevel::SafeWrite => SafetyLevel::SafeWrite,
278 }
279 }
280}
281
282#[derive(Debug)]
283pub struct CommandSpec {
284 pub name: String,
285 pub description: String,
286 pub aliases: Vec<String>,
287 pub url: String,
288 pub category: String,
289 pub researched_version: Option<String>,
296 pub examples_safe: Vec<String>,
299 pub examples_denied: Vec<String>,
303 pub eval_safe: bool,
306 pub eval_safe_flags: Vec<String>,
309 pub(super) kind: DispatchKind,
310}
311
312#[derive(Debug, Clone)]
313pub(super) struct SubSpec {
314 pub name: String,
315 pub kind: DispatchKind,
316 pub policy_ref: Option<String>,
321 pub eval_safe: bool,
324 pub eval_safe_flags: Vec<String>,
327}
328
329#[derive(Debug, Clone)]
330pub(super) enum DispatchKind {
331 Policy {
332 policy: OwnedPolicy,
333 level: SafetyLevel,
334 },
335 FirstArg {
336 patterns: Vec<String>,
337 level: SafetyLevel,
338 },
339 RequireAny {
340 require_any: Vec<String>,
341 policy: OwnedPolicy,
342 level: SafetyLevel,
343 accept_bare_help: bool,
344 },
345 Branching {
346 subs: Vec<SubSpec>,
347 bare_flags: Vec<String>,
348 bare_ok: bool,
349 pre_standalone: Vec<String>,
350 pre_valued: Vec<String>,
351 first_arg: Vec<String>,
352 first_arg_level: SafetyLevel,
353 },
354 WriteFlagged {
355 policy: OwnedPolicy,
356 base_level: SafetyLevel,
357 write_flags: Vec<String>,
358 },
359 DelegateAfterSeparator {
360 separator: String,
361 },
362 DelegateSkip {
363 skip: usize,
364 },
365 Wrapper {
366 standalone: Vec<String>,
367 valued: Vec<String>,
368 positional_skip: usize,
369 separator: Option<String>,
370 bare_ok: bool,
371 },
372 Custom {
373 #[allow(dead_code)]
374 handler_name: String,
375 doc_body: Option<String>,
376 subs: Vec<SubSpec>,
380 fallback: Option<FallbackSpec>,
384 handler_policies: std::collections::HashMap<String, OwnedPolicy>,
388 matrices: Vec<MatrixSpec>,
391 },
392}
393
394#[derive(Debug, Clone)]
395pub struct OwnedPolicy {
396 pub standalone: Vec<String>,
397 pub valued: Vec<String>,
398 pub bare: bool,
399 pub max_positional: Option<usize>,
400 pub tolerance: crate::policy::FlagTolerance,
401}
402
403#[derive(Debug, Clone)]
404pub(super) struct MatrixSpec {
405 pub parents: Vec<String>,
406 pub level: SafetyLevel,
407 pub actions: std::collections::HashMap<String, MatrixAction>,
408}
409
410#[derive(Debug, Clone)]
411pub(super) struct MatrixAction {
412 pub policy_key: String,
413 pub guard: Option<String>,
414 pub guard_short: Option<String>,
415}
416
417#[derive(Debug, Clone)]
418pub(super) struct FallbackSpec {
419 pub policy: OwnedPolicy,
420 pub level: SafetyLevel,
421 pub positional_shape: Option<crate::policy::PositionalShape>,
422}