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