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