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}
75
76#[derive(Debug, Deserialize)]
77pub(super) struct TomlWrapper {
78 #[serde(default)]
79 pub standalone: Vec<String>,
80 #[serde(default)]
81 pub valued: Vec<String>,
82 #[serde(default)]
83 pub positional_skip: Option<usize>,
84 #[serde(default)]
85 pub separator: Option<String>,
86 #[serde(default)]
87 pub bare_ok: Option<bool>,
88}
89
90#[derive(Debug, Deserialize)]
91pub(super) struct TomlSub {
92 pub name: String,
93 #[serde(default)]
94 pub candidate: Option<bool>,
95 #[serde(default)]
96 pub aliases: Vec<String>,
97 #[serde(default)]
98 pub level: Option<TomlLevel>,
99 #[serde(default)]
100 pub bare: Option<bool>,
101 #[serde(default)]
102 pub max_positional: Option<usize>,
103 #[serde(default)]
105 pub positional_style: Option<bool>,
106 #[serde(default)]
107 pub tolerate_unknown_short: Option<bool>,
108 #[serde(default)]
109 pub tolerate_unknown_long: Option<bool>,
110 #[serde(default)]
111 pub numeric_dash: Option<bool>,
112 #[serde(default)]
113 pub standalone: Vec<String>,
114 #[serde(default)]
115 pub valued: Vec<String>,
116 #[serde(default)]
117 pub guard: Option<String>,
118 #[serde(default)]
119 pub guard_short: Option<String>,
120 #[serde(default)]
121 pub allow_all: Option<bool>,
122 #[serde(default)]
123 pub sub: Vec<TomlSub>,
124 #[serde(default)]
125 pub nested_bare: Option<bool>,
126 #[serde(default)]
127 pub require_any: Vec<String>,
128 #[serde(default)]
129 pub first_arg: Vec<String>,
130 #[serde(default)]
131 pub write_flags: Vec<String>,
132 #[serde(default)]
133 pub delegate_after: Option<String>,
134 #[serde(default)]
135 pub delegate_skip: Option<usize>,
136 #[serde(default)]
137 pub handler: Option<String>,
138 #[serde(default)]
139 pub doc_body: Option<String>,
140}
141
142#[derive(Debug, Clone, Copy, Deserialize)]
143pub(super) enum TomlLevel {
144 Inert,
145 SafeRead,
146 SafeWrite,
147}
148
149impl From<TomlLevel> for SafetyLevel {
150 fn from(l: TomlLevel) -> Self {
151 match l {
152 TomlLevel::Inert => SafetyLevel::Inert,
153 TomlLevel::SafeRead => SafetyLevel::SafeRead,
154 TomlLevel::SafeWrite => SafetyLevel::SafeWrite,
155 }
156 }
157}
158
159#[derive(Debug)]
160pub struct CommandSpec {
161 pub name: String,
162 pub description: String,
163 pub aliases: Vec<String>,
164 pub url: String,
165 pub category: String,
166 pub researched_version: Option<String>,
173 pub examples_safe: Vec<String>,
176 pub examples_denied: Vec<String>,
180 pub(super) kind: DispatchKind,
181}
182
183#[derive(Debug, Clone)]
184pub(super) struct SubSpec {
185 pub name: String,
186 pub kind: DispatchKind,
187}
188
189#[derive(Debug, Clone)]
190pub(super) enum DispatchKind {
191 Policy {
192 policy: OwnedPolicy,
193 level: SafetyLevel,
194 },
195 FirstArg {
196 patterns: Vec<String>,
197 level: SafetyLevel,
198 },
199 RequireAny {
200 require_any: Vec<String>,
201 policy: OwnedPolicy,
202 level: SafetyLevel,
203 accept_bare_help: bool,
204 },
205 Branching {
206 subs: Vec<SubSpec>,
207 bare_flags: Vec<String>,
208 bare_ok: bool,
209 pre_standalone: Vec<String>,
210 pre_valued: Vec<String>,
211 first_arg: Vec<String>,
212 first_arg_level: SafetyLevel,
213 },
214 WriteFlagged {
215 policy: OwnedPolicy,
216 base_level: SafetyLevel,
217 write_flags: Vec<String>,
218 },
219 DelegateAfterSeparator {
220 separator: String,
221 },
222 DelegateSkip {
223 skip: usize,
224 },
225 Wrapper {
226 standalone: Vec<String>,
227 valued: Vec<String>,
228 positional_skip: usize,
229 separator: Option<String>,
230 bare_ok: bool,
231 },
232 Custom {
233 #[allow(dead_code)]
234 handler_name: String,
235 doc_body: Option<String>,
236 },
237}
238
239#[derive(Debug, Clone)]
240pub struct OwnedPolicy {
241 pub standalone: Vec<String>,
242 pub valued: Vec<String>,
243 pub bare: bool,
244 pub max_positional: Option<usize>,
245 pub tolerance: crate::policy::FlagTolerance,
246}