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