vtx_sdk/core/
capabilities.rs1use crate::error::VtxError;
4use crate::{Capabilities, HttpAllowRule};
5
6pub const PERM_BUFFER_CREATE: &str = "buffer:create";
7pub const PERM_FILE_READ: &str = "file:read";
8pub const PERM_FILE_WRITE: &str = "file:write";
9pub const PERM_FFMPEG_EXECUTE: &str = "ffmpeg:execute";
10pub const PERM_SQL_WRITE: &str = "sql:write";
11
12pub trait CapabilitiesExt {
13 fn has_permission(&self, perm: &str) -> bool;
14}
15
16impl CapabilitiesExt for Capabilities {
17 fn has_permission(&self, perm: &str) -> bool {
18 self.permissions.iter().any(|p| p == perm)
19 }
20}
21
22pub trait VtxErrorExt {
23 fn is_permission_denied(&self) -> bool;
24}
25
26impl VtxErrorExt for VtxError {
27 fn is_permission_denied(&self) -> bool {
28 matches!(self, VtxError::PermissionDenied(_))
29 }
30}
31
32pub struct CapabilitiesBuilder {
34 subscriptions: Vec<String>,
35 permissions: Vec<String>,
36 http: Vec<HttpAllowRule>,
37}
38
39impl CapabilitiesBuilder {
40 pub fn new() -> Self {
41 Self {
42 subscriptions: Vec::new(),
43 permissions: Vec::new(),
44 http: Vec::new(),
45 }
46 }
47
48 pub fn subscription(mut self, topic: impl Into<String>) -> Self {
49 self.subscriptions.push(topic.into());
50 self
51 }
52
53 pub fn subscriptions<I, S>(mut self, topics: I) -> Self
54 where
55 I: IntoIterator<Item = S>,
56 S: Into<String>,
57 {
58 self.subscriptions
59 .extend(topics.into_iter().map(Into::into));
60 self
61 }
62
63 pub fn permission(mut self, perm: impl Into<String>) -> Self {
64 self.permissions.push(perm.into());
65 self
66 }
67
68 pub fn permissions<I, S>(mut self, perms: I) -> Self
69 where
70 I: IntoIterator<Item = S>,
71 S: Into<String>,
72 {
73 self.permissions.extend(perms.into_iter().map(Into::into));
74 self
75 }
76
77 pub fn http_rule(mut self, rule: HttpAllowRule) -> Self {
78 self.http.push(rule);
79 self
80 }
81
82 pub fn http_rules<I>(mut self, rules: I) -> Self
83 where
84 I: IntoIterator<Item = HttpAllowRule>,
85 {
86 self.http.extend(rules);
87 self
88 }
89
90 pub fn build(self) -> Capabilities {
91 let http = if self.http.is_empty() {
92 None
93 } else {
94 Some(self.http)
95 };
96 Capabilities {
97 subscriptions: self.subscriptions,
98 permissions: self.permissions,
99 http,
100 }
101 }
102}
103
104impl Default for CapabilitiesBuilder {
105 fn default() -> Self {
106 Self::new()
107 }
108}
109
110pub struct HttpAllowRuleBuilder {
112 scheme: String,
113 host: String,
114 port: Option<u16>,
115 path: Option<String>,
116 methods: Option<Vec<String>>,
117 allow_headers: Option<Vec<String>>,
118 max_request_bytes: Option<u64>,
119 max_response_bytes: Option<u64>,
120 follow_redirects: Option<bool>,
121 redirect_policy: Option<String>,
122}
123
124impl HttpAllowRuleBuilder {
125 pub fn new(scheme: impl Into<String>, host: impl Into<String>) -> Self {
126 Self {
127 scheme: scheme.into(),
128 host: host.into(),
129 port: None,
130 path: None,
131 methods: None,
132 allow_headers: None,
133 max_request_bytes: None,
134 max_response_bytes: None,
135 follow_redirects: None,
136 redirect_policy: None,
137 }
138 }
139
140 pub fn port(mut self, port: u16) -> Self {
141 self.port = Some(port);
142 self
143 }
144
145 pub fn path(mut self, path: impl Into<String>) -> Self {
146 self.path = Some(path.into());
147 self
148 }
149
150 pub fn methods<I, S>(mut self, methods: I) -> Self
151 where
152 I: IntoIterator<Item = S>,
153 S: Into<String>,
154 {
155 self.methods = Some(methods.into_iter().map(Into::into).collect());
156 self
157 }
158
159 pub fn allow_headers<I, S>(mut self, headers: I) -> Self
160 where
161 I: IntoIterator<Item = S>,
162 S: Into<String>,
163 {
164 self.allow_headers = Some(headers.into_iter().map(Into::into).collect());
165 self
166 }
167
168 pub fn max_request_bytes(mut self, bytes: u64) -> Self {
169 self.max_request_bytes = Some(bytes);
170 self
171 }
172
173 pub fn max_response_bytes(mut self, bytes: u64) -> Self {
174 self.max_response_bytes = Some(bytes);
175 self
176 }
177
178 pub fn follow_redirects(mut self, enabled: bool) -> Self {
179 self.follow_redirects = Some(enabled);
180 self
181 }
182
183 pub fn redirect_policy(mut self, policy: impl Into<String>) -> Self {
184 self.redirect_policy = Some(policy.into());
185 self
186 }
187
188 pub fn build(self) -> HttpAllowRule {
189 HttpAllowRule {
190 scheme: self.scheme,
191 host: self.host,
192 port: self.port,
193 path: self.path,
194 methods: self.methods,
195 allow_headers: self.allow_headers,
196 max_request_bytes: self.max_request_bytes,
197 max_response_bytes: self.max_response_bytes,
198 follow_redirects: self.follow_redirects,
199 redirect_policy: self.redirect_policy,
200 }
201 }
202}