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 description: Option<String>,
16 #[serde(default)]
17 pub candidate: Option<bool>,
18 #[serde(default)]
19 pub aliases: Vec<String>,
20 #[serde(default)]
21 pub url: String,
22 #[serde(default)]
23 pub level: Option<TomlLevel>,
24 #[serde(default)]
25 pub bare: Option<bool>,
26 #[serde(default)]
27 pub max_positional: Option<usize>,
28 #[serde(default)]
29 pub positional_style: Option<bool>,
30 #[serde(default)]
31 pub numeric_dash: Option<bool>,
32 #[serde(default)]
33 pub standalone: Vec<String>,
34 #[serde(default)]
35 pub valued: Vec<String>,
36 #[serde(default)]
37 pub bare_flags: Vec<String>,
38 #[serde(default)]
39 pub sub: Vec<TomlSub>,
40 #[serde(default)]
41 pub handler: Option<String>,
42 #[serde(default)]
43 pub doc_body: Option<String>,
44 #[serde(default)]
45 pub require_any: Vec<String>,
46 #[serde(default)]
47 pub first_arg: Vec<String>,
48 #[serde(default)]
49 pub wrapper: Option<TomlWrapper>,
50 #[serde(default)]
51 pub write_flags: Vec<String>,
52 #[serde(default)]
53 pub researched_version: Option<String>,
54 #[serde(default)]
59 pub examples_safe: Vec<String>,
60 #[serde(default)]
61 pub examples_denied: Vec<String>,
62 #[serde(default)]
66 pub deny: Option<bool>,
67}
68
69#[derive(Debug, Deserialize)]
70pub(super) struct TomlWrapper {
71 #[serde(default)]
72 pub standalone: Vec<String>,
73 #[serde(default)]
74 pub valued: Vec<String>,
75 #[serde(default)]
76 pub positional_skip: Option<usize>,
77 #[serde(default)]
78 pub separator: Option<String>,
79 #[serde(default)]
80 pub bare_ok: Option<bool>,
81}
82
83#[derive(Debug, Deserialize)]
84pub(super) struct TomlSub {
85 pub name: String,
86 #[serde(default)]
87 pub candidate: Option<bool>,
88 #[serde(default)]
89 pub aliases: Vec<String>,
90 #[serde(default)]
91 pub level: Option<TomlLevel>,
92 #[serde(default)]
93 pub bare: Option<bool>,
94 #[serde(default)]
95 pub max_positional: Option<usize>,
96 #[serde(default)]
97 pub positional_style: Option<bool>,
98 #[serde(default)]
99 pub numeric_dash: Option<bool>,
100 #[serde(default)]
101 pub standalone: Vec<String>,
102 #[serde(default)]
103 pub valued: Vec<String>,
104 #[serde(default)]
105 pub guard: Option<String>,
106 #[serde(default)]
107 pub guard_short: Option<String>,
108 #[serde(default)]
109 pub allow_all: Option<bool>,
110 #[serde(default)]
111 pub sub: Vec<TomlSub>,
112 #[serde(default)]
113 pub nested_bare: Option<bool>,
114 #[serde(default)]
115 pub require_any: Vec<String>,
116 #[serde(default)]
117 pub first_arg: Vec<String>,
118 #[serde(default)]
119 pub write_flags: Vec<String>,
120 #[serde(default)]
121 pub delegate_after: Option<String>,
122 #[serde(default)]
123 pub delegate_skip: Option<usize>,
124 #[serde(default)]
125 pub handler: Option<String>,
126 #[serde(default)]
127 pub doc_body: Option<String>,
128}
129
130#[derive(Debug, Clone, Copy, Deserialize)]
131pub(super) enum TomlLevel {
132 Inert,
133 SafeRead,
134 SafeWrite,
135}
136
137impl From<TomlLevel> for SafetyLevel {
138 fn from(l: TomlLevel) -> Self {
139 match l {
140 TomlLevel::Inert => SafetyLevel::Inert,
141 TomlLevel::SafeRead => SafetyLevel::SafeRead,
142 TomlLevel::SafeWrite => SafetyLevel::SafeWrite,
143 }
144 }
145}
146
147#[derive(Debug)]
148pub struct CommandSpec {
149 pub name: String,
150 pub description: String,
151 pub aliases: Vec<String>,
152 pub url: String,
153 pub category: String,
154 pub researched_version: Option<String>,
161 pub examples_safe: Vec<String>,
164 pub examples_denied: Vec<String>,
168 pub(super) kind: DispatchKind,
169}
170
171#[derive(Debug, Clone)]
172pub(super) struct SubSpec {
173 pub name: String,
174 pub kind: DispatchKind,
175}
176
177#[derive(Debug, Clone)]
178pub(super) enum DispatchKind {
179 Policy {
180 policy: OwnedPolicy,
181 level: SafetyLevel,
182 },
183 FirstArg {
184 patterns: Vec<String>,
185 level: SafetyLevel,
186 },
187 RequireAny {
188 require_any: Vec<String>,
189 policy: OwnedPolicy,
190 level: SafetyLevel,
191 accept_bare_help: bool,
192 },
193 Branching {
194 subs: Vec<SubSpec>,
195 bare_flags: Vec<String>,
196 bare_ok: bool,
197 pre_standalone: Vec<String>,
198 pre_valued: Vec<String>,
199 first_arg: Vec<String>,
200 first_arg_level: SafetyLevel,
201 },
202 WriteFlagged {
203 policy: OwnedPolicy,
204 base_level: SafetyLevel,
205 write_flags: Vec<String>,
206 },
207 DelegateAfterSeparator {
208 separator: String,
209 },
210 DelegateSkip {
211 skip: usize,
212 },
213 Wrapper {
214 standalone: Vec<String>,
215 valued: Vec<String>,
216 positional_skip: usize,
217 separator: Option<String>,
218 bare_ok: bool,
219 },
220 Custom {
221 #[allow(dead_code)]
222 handler_name: String,
223 doc_body: Option<String>,
224 },
225}
226
227#[derive(Debug, Clone)]
228pub struct OwnedPolicy {
229 pub standalone: Vec<String>,
230 pub valued: Vec<String>,
231 pub bare: bool,
232 pub max_positional: Option<usize>,
233 pub flag_style: FlagStyle,
234 pub numeric_dash: bool,
235}