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