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