Skip to main content

safe_chains/registry/
types.rs

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: CommandKind,
126}
127
128#[derive(Debug)]
129pub(super) enum CommandKind {
130    Flat {
131        policy: OwnedPolicy,
132        level: SafetyLevel,
133    },
134    FlatRequireAny {
135        require_any: Vec<String>,
136        policy: OwnedPolicy,
137        level: SafetyLevel,
138    },
139    FlatFirstArg {
140        patterns: Vec<String>,
141        level: SafetyLevel,
142    },
143    Structured {
144        bare_flags: Vec<String>,
145        subs: Vec<SubSpec>,
146        pre_standalone: Vec<String>,
147        pre_valued: Vec<String>,
148        bare_ok: bool,
149        first_arg: Vec<String>,
150        first_arg_level: SafetyLevel,
151    },
152    Wrapper {
153        standalone: Vec<String>,
154        valued: Vec<String>,
155        positional_skip: usize,
156        separator: Option<String>,
157        bare_ok: bool,
158    },
159    Custom {
160        #[allow(dead_code)]
161        handler_name: String,
162    },
163}
164
165#[derive(Debug)]
166pub(super) struct SubSpec {
167    pub name: String,
168    pub kind: SubKind,
169}
170
171#[derive(Debug)]
172pub(super) enum SubKind {
173    Policy {
174        policy: OwnedPolicy,
175        level: SafetyLevel,
176    },
177    Guarded {
178        guard_long: String,
179        guard_short: Option<String>,
180        policy: OwnedPolicy,
181        level: SafetyLevel,
182    },
183    Nested {
184        subs: Vec<SubSpec>,
185        allow_bare: bool,
186    },
187    AllowAll {
188        level: SafetyLevel,
189    },
190    WriteFlagged {
191        policy: OwnedPolicy,
192        base_level: SafetyLevel,
193        write_flags: Vec<String>,
194    },
195    FirstArgFilter {
196        patterns: Vec<String>,
197        level: SafetyLevel,
198    },
199    RequireAny {
200        require_any: Vec<String>,
201        policy: OwnedPolicy,
202        level: SafetyLevel,
203    },
204    DelegateAfterSeparator {
205        separator: String,
206    },
207    DelegateSkip {
208        skip: usize,
209        #[allow(dead_code)]
210        doc: String,
211    },
212    Custom {
213        #[allow(dead_code)]
214        handler_name: String,
215    },
216}
217
218#[derive(Debug)]
219pub struct OwnedPolicy {
220    pub standalone: Vec<String>,
221    pub valued: Vec<String>,
222    pub bare: bool,
223    pub max_positional: Option<usize>,
224    pub flag_style: FlagStyle,
225}