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)]
92 pub handler_data: std::collections::HashMap<String, Vec<String>>,
93 #[serde(default)]
99 pub matrix: Vec<TomlMatrix>,
100}
101
102#[derive(Debug, Deserialize)]
103pub(super) struct TomlMatrix {
104 pub parents: Vec<String>,
105 pub level: TomlLevel,
106 pub actions: std::collections::HashMap<String, TomlMatrixAction>,
107}
108
109#[derive(Debug, Deserialize)]
110#[serde(untagged)]
111pub(super) enum TomlMatrixAction {
112 Policy(String),
115 Detailed {
119 policy: String,
120 #[serde(default)]
121 guard: Option<String>,
122 #[serde(default)]
123 guard_short: Option<String>,
124 },
125}
126
127#[derive(Debug, Deserialize)]
128pub(super) struct TomlHandlerPolicy {
129 #[serde(default)]
130 pub standalone: Vec<String>,
131 #[serde(default)]
132 pub valued: Vec<String>,
133 #[serde(default)]
134 pub bare: Option<bool>,
135 #[serde(default)]
136 pub max_positional: Option<usize>,
137 #[serde(default)]
138 pub tolerate_unknown_short: Option<bool>,
139 #[serde(default)]
140 pub tolerate_unknown_long: Option<bool>,
141 #[serde(default)]
142 pub numeric_dash: Option<bool>,
143}
144
145#[derive(Debug, Deserialize)]
146pub(super) struct TomlFallback {
147 #[serde(default)]
148 pub level: Option<TomlLevel>,
149 #[serde(default)]
150 pub bare: Option<bool>,
151 #[serde(default)]
152 pub max_positional: Option<usize>,
153 #[serde(default)]
154 pub standalone: Vec<String>,
155 #[serde(default)]
156 pub valued: Vec<String>,
157 #[serde(default)]
158 pub tolerate_unknown_short: Option<bool>,
159 #[serde(default)]
160 pub tolerate_unknown_long: Option<bool>,
161 #[serde(default)]
162 pub numeric_dash: Option<bool>,
163 #[serde(default)]
169 pub positional_shape: Option<String>,
170}
171
172#[derive(Debug, Deserialize)]
173pub(super) struct TomlWrapper {
174 #[serde(default)]
175 pub standalone: Vec<String>,
176 #[serde(default)]
177 pub valued: Vec<String>,
178 #[serde(default)]
179 pub positional_skip: Option<usize>,
180 #[serde(default)]
181 pub separator: Option<String>,
182 #[serde(default)]
183 pub bare_ok: Option<bool>,
184}
185
186#[derive(Debug, Deserialize)]
187pub(super) struct TomlSub {
188 pub name: String,
189 #[serde(default)]
190 pub candidate: Option<bool>,
191 #[serde(default)]
192 pub aliases: Vec<String>,
193 #[serde(default)]
194 pub level: Option<TomlLevel>,
195 #[serde(default)]
196 pub bare: Option<bool>,
197 #[serde(default)]
198 pub max_positional: Option<usize>,
199 #[serde(default)]
201 pub positional_style: Option<bool>,
202 #[serde(default)]
203 pub tolerate_unknown_short: Option<bool>,
204 #[serde(default)]
205 pub tolerate_unknown_long: Option<bool>,
206 #[serde(default)]
207 pub numeric_dash: Option<bool>,
208 #[serde(default)]
209 pub standalone: Vec<String>,
210 #[serde(default)]
211 pub valued: Vec<String>,
212 #[serde(default)]
213 pub guard: Option<String>,
214 #[serde(default)]
215 pub guard_short: Option<String>,
216 #[serde(default)]
217 pub allow_all: Option<bool>,
218 #[serde(default)]
224 pub policy: Option<String>,
225 #[serde(default)]
226 pub sub: Vec<TomlSub>,
227 #[serde(default)]
228 pub nested_bare: Option<bool>,
229 #[serde(default)]
230 pub require_any: Vec<String>,
231 #[serde(default)]
232 pub first_arg: Vec<String>,
233 #[serde(default)]
234 pub write_flags: Vec<String>,
235 #[serde(default)]
236 pub delegate_after: Option<String>,
237 #[serde(default)]
238 pub delegate_skip: Option<usize>,
239 #[serde(default)]
240 pub handler: Option<String>,
241 #[serde(default)]
242 pub doc_body: Option<String>,
243}
244
245#[derive(Debug, Clone, Copy, Deserialize)]
246pub(super) enum TomlLevel {
247 Inert,
248 SafeRead,
249 SafeWrite,
250}
251
252impl From<TomlLevel> for SafetyLevel {
253 fn from(l: TomlLevel) -> Self {
254 match l {
255 TomlLevel::Inert => SafetyLevel::Inert,
256 TomlLevel::SafeRead => SafetyLevel::SafeRead,
257 TomlLevel::SafeWrite => SafetyLevel::SafeWrite,
258 }
259 }
260}
261
262#[derive(Debug)]
263pub struct CommandSpec {
264 pub name: String,
265 pub description: String,
266 pub aliases: Vec<String>,
267 pub url: String,
268 pub category: String,
269 pub researched_version: Option<String>,
276 pub examples_safe: Vec<String>,
279 pub examples_denied: Vec<String>,
283 pub(super) kind: DispatchKind,
284}
285
286#[derive(Debug, Clone)]
287pub(super) struct SubSpec {
288 pub name: String,
289 pub kind: DispatchKind,
290 pub policy_ref: Option<String>,
295}
296
297#[derive(Debug, Clone)]
298pub(super) enum DispatchKind {
299 Policy {
300 policy: OwnedPolicy,
301 level: SafetyLevel,
302 },
303 FirstArg {
304 patterns: Vec<String>,
305 level: SafetyLevel,
306 },
307 RequireAny {
308 require_any: Vec<String>,
309 policy: OwnedPolicy,
310 level: SafetyLevel,
311 accept_bare_help: bool,
312 },
313 Branching {
314 subs: Vec<SubSpec>,
315 bare_flags: Vec<String>,
316 bare_ok: bool,
317 pre_standalone: Vec<String>,
318 pre_valued: Vec<String>,
319 first_arg: Vec<String>,
320 first_arg_level: SafetyLevel,
321 },
322 WriteFlagged {
323 policy: OwnedPolicy,
324 base_level: SafetyLevel,
325 write_flags: Vec<String>,
326 },
327 DelegateAfterSeparator {
328 separator: String,
329 },
330 DelegateSkip {
331 skip: usize,
332 },
333 Wrapper {
334 standalone: Vec<String>,
335 valued: Vec<String>,
336 positional_skip: usize,
337 separator: Option<String>,
338 bare_ok: bool,
339 },
340 Custom {
341 #[allow(dead_code)]
342 handler_name: String,
343 doc_body: Option<String>,
344 subs: Vec<SubSpec>,
348 fallback: Option<FallbackSpec>,
352 handler_policies: std::collections::HashMap<String, OwnedPolicy>,
356 handler_data: std::collections::HashMap<String, Vec<String>>,
359 matrices: Vec<MatrixSpec>,
362 },
363}
364
365#[derive(Debug, Clone)]
366pub struct OwnedPolicy {
367 pub standalone: Vec<String>,
368 pub valued: Vec<String>,
369 pub bare: bool,
370 pub max_positional: Option<usize>,
371 pub tolerance: crate::policy::FlagTolerance,
372}
373
374#[derive(Debug, Clone)]
375pub(super) struct MatrixSpec {
376 pub parents: Vec<String>,
377 pub level: SafetyLevel,
378 pub actions: std::collections::HashMap<String, MatrixAction>,
379}
380
381#[derive(Debug, Clone)]
382pub(super) struct MatrixAction {
383 pub policy_key: String,
384 pub guard: Option<String>,
385 pub guard_short: Option<String>,
386}
387
388#[derive(Debug, Clone)]
389pub(super) struct FallbackSpec {
390 pub policy: OwnedPolicy,
391 pub level: SafetyLevel,
392 pub positional_shape: Option<crate::policy::PositionalShape>,
393}