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