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}
55
56#[derive(Debug, Deserialize)]
57pub(super) struct TomlWrapper {
58 #[serde(default)]
59 pub standalone: Vec<String>,
60 #[serde(default)]
61 pub valued: Vec<String>,
62 #[serde(default)]
63 pub positional_skip: Option<usize>,
64 #[serde(default)]
65 pub separator: Option<String>,
66 #[serde(default)]
67 pub bare_ok: Option<bool>,
68}
69
70#[derive(Debug, Deserialize)]
71pub(super) struct TomlSub {
72 pub name: String,
73 #[serde(default)]
74 pub candidate: Option<bool>,
75 #[serde(default)]
76 pub level: Option<TomlLevel>,
77 #[serde(default)]
78 pub bare: Option<bool>,
79 #[serde(default)]
80 pub max_positional: Option<usize>,
81 #[serde(default)]
82 pub positional_style: Option<bool>,
83 #[serde(default)]
84 pub numeric_dash: Option<bool>,
85 #[serde(default)]
86 pub standalone: Vec<String>,
87 #[serde(default)]
88 pub valued: Vec<String>,
89 #[serde(default)]
90 pub guard: Option<String>,
91 #[serde(default)]
92 pub guard_short: Option<String>,
93 #[serde(default)]
94 pub allow_all: Option<bool>,
95 #[serde(default)]
96 pub sub: Vec<TomlSub>,
97 #[serde(default)]
98 pub nested_bare: Option<bool>,
99 #[serde(default)]
100 pub require_any: Vec<String>,
101 #[serde(default)]
102 pub first_arg: Vec<String>,
103 #[serde(default)]
104 pub write_flags: Vec<String>,
105 #[serde(default)]
106 pub delegate_after: Option<String>,
107 #[serde(default)]
108 pub delegate_skip: Option<usize>,
109 #[serde(default)]
110 pub handler: Option<String>,
111 #[serde(default)]
112 pub doc_body: Option<String>,
113}
114
115#[derive(Debug, Clone, Copy, Deserialize)]
116pub(super) enum TomlLevel {
117 Inert,
118 SafeRead,
119 SafeWrite,
120}
121
122impl From<TomlLevel> for SafetyLevel {
123 fn from(l: TomlLevel) -> Self {
124 match l {
125 TomlLevel::Inert => SafetyLevel::Inert,
126 TomlLevel::SafeRead => SafetyLevel::SafeRead,
127 TomlLevel::SafeWrite => SafetyLevel::SafeWrite,
128 }
129 }
130}
131
132#[derive(Debug)]
133pub struct CommandSpec {
134 pub name: String,
135 pub description: String,
136 pub aliases: Vec<String>,
137 pub url: String,
138 pub category: String,
139 pub researched_version: Option<String>,
146 pub(super) kind: DispatchKind,
147}
148
149#[derive(Debug, Clone)]
150pub(super) struct SubSpec {
151 pub name: String,
152 pub kind: DispatchKind,
153}
154
155#[derive(Debug, Clone)]
156pub(super) enum DispatchKind {
157 Policy {
158 policy: OwnedPolicy,
159 level: SafetyLevel,
160 },
161 FirstArg {
162 patterns: Vec<String>,
163 level: SafetyLevel,
164 },
165 RequireAny {
166 require_any: Vec<String>,
167 policy: OwnedPolicy,
168 level: SafetyLevel,
169 accept_bare_help: bool,
170 },
171 Branching {
172 subs: Vec<SubSpec>,
173 bare_flags: Vec<String>,
174 bare_ok: bool,
175 pre_standalone: Vec<String>,
176 pre_valued: Vec<String>,
177 first_arg: Vec<String>,
178 first_arg_level: SafetyLevel,
179 },
180 WriteFlagged {
181 policy: OwnedPolicy,
182 base_level: SafetyLevel,
183 write_flags: Vec<String>,
184 },
185 DelegateAfterSeparator {
186 separator: String,
187 },
188 DelegateSkip {
189 skip: usize,
190 },
191 Wrapper {
192 standalone: Vec<String>,
193 valued: Vec<String>,
194 positional_skip: usize,
195 separator: Option<String>,
196 bare_ok: bool,
197 },
198 Custom {
199 #[allow(dead_code)]
200 handler_name: String,
201 doc_body: Option<String>,
202 },
203}
204
205#[derive(Debug, Clone)]
206pub struct OwnedPolicy {
207 pub standalone: Vec<String>,
208 pub valued: Vec<String>,
209 pub bare: bool,
210 pub max_positional: Option<usize>,
211 pub flag_style: FlagStyle,
212 pub numeric_dash: bool,
213}