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    },
149    Wrapper {
150        standalone: Vec<String>,
151        valued: Vec<String>,
152        positional_skip: usize,
153        separator: Option<String>,
154        bare_ok: bool,
155    },
156    Custom {
157        #[allow(dead_code)]
158        handler_name: String,
159    },
160}
161
162#[derive(Debug)]
163pub(super) struct SubSpec {
164    pub name: String,
165    pub kind: SubKind,
166}
167
168#[derive(Debug)]
169pub(super) enum SubKind {
170    Policy {
171        policy: OwnedPolicy,
172        level: SafetyLevel,
173    },
174    Guarded {
175        guard_long: String,
176        guard_short: Option<String>,
177        policy: OwnedPolicy,
178        level: SafetyLevel,
179    },
180    Nested {
181        subs: Vec<SubSpec>,
182        allow_bare: bool,
183    },
184    AllowAll {
185        level: SafetyLevel,
186    },
187    WriteFlagged {
188        policy: OwnedPolicy,
189        base_level: SafetyLevel,
190        write_flags: Vec<String>,
191    },
192    FirstArgFilter {
193        patterns: Vec<String>,
194        level: SafetyLevel,
195    },
196    RequireAny {
197        require_any: Vec<String>,
198        policy: OwnedPolicy,
199        level: SafetyLevel,
200    },
201    DelegateAfterSeparator {
202        separator: String,
203    },
204    DelegateSkip {
205        skip: usize,
206        #[allow(dead_code)]
207        doc: String,
208    },
209    Custom {
210        #[allow(dead_code)]
211        handler_name: String,
212    },
213}
214
215#[derive(Debug)]
216pub struct OwnedPolicy {
217    pub standalone: Vec<String>,
218    pub valued: Vec<String>,
219    pub bare: bool,
220    pub max_positional: Option<usize>,
221    pub flag_style: FlagStyle,
222}