drizzle_types/postgres/ddl/
role.rs1#[cfg(feature = "std")]
6use std::borrow::Cow;
7
8#[cfg(all(feature = "alloc", not(feature = "std")))]
9use alloc::borrow::Cow;
10
11#[cfg(feature = "serde")]
12use crate::serde_helpers::{cow_from_string, cow_option_from_string};
13
14#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
20pub struct RoleDef {
21 pub name: &'static str,
23 pub superuser: Option<bool>,
25 pub create_db: Option<bool>,
27 pub create_role: Option<bool>,
29 pub inherit: Option<bool>,
31 pub can_login: Option<bool>,
33 pub replication: Option<bool>,
35 pub bypass_rls: Option<bool>,
37 pub conn_limit: Option<i32>,
39 pub password: Option<&'static str>,
41 pub valid_until: Option<&'static str>,
43}
44
45impl RoleDef {
46 #[must_use]
48 pub const fn new(name: &'static str) -> Self {
49 Self {
50 name,
51 superuser: None,
52 create_db: None,
53 create_role: None,
54 inherit: None,
55 can_login: None,
56 replication: None,
57 bypass_rls: None,
58 conn_limit: None,
59 password: None,
60 valid_until: None,
61 }
62 }
63
64 #[must_use]
66 pub const fn superuser(self, value: bool) -> Self {
67 Self {
68 superuser: Some(value),
69 ..self
70 }
71 }
72
73 #[must_use]
75 pub const fn create_db(self, value: bool) -> Self {
76 Self {
77 create_db: Some(value),
78 ..self
79 }
80 }
81
82 #[must_use]
84 pub const fn create_role(self, value: bool) -> Self {
85 Self {
86 create_role: Some(value),
87 ..self
88 }
89 }
90
91 #[must_use]
93 pub const fn inherit(self, value: bool) -> Self {
94 Self {
95 inherit: Some(value),
96 ..self
97 }
98 }
99
100 #[must_use]
102 pub const fn can_login(self, value: bool) -> Self {
103 Self {
104 can_login: Some(value),
105 ..self
106 }
107 }
108
109 #[must_use]
111 pub const fn replication(self, value: bool) -> Self {
112 Self {
113 replication: Some(value),
114 ..self
115 }
116 }
117
118 #[must_use]
120 pub const fn bypass_rls(self, value: bool) -> Self {
121 Self {
122 bypass_rls: Some(value),
123 ..self
124 }
125 }
126
127 #[must_use]
129 pub const fn conn_limit(self, limit: i32) -> Self {
130 Self {
131 conn_limit: Some(limit),
132 ..self
133 }
134 }
135
136 #[must_use]
138 pub const fn password(self, password: &'static str) -> Self {
139 Self {
140 password: Some(password),
141 ..self
142 }
143 }
144
145 #[must_use]
147 pub const fn valid_until(self, date: &'static str) -> Self {
148 Self {
149 valid_until: Some(date),
150 ..self
151 }
152 }
153
154 #[must_use]
156 pub const fn into_role(self) -> Role {
157 Role {
158 name: Cow::Borrowed(self.name),
159 superuser: self.superuser,
160 create_db: self.create_db,
161 create_role: self.create_role,
162 inherit: self.inherit,
163 can_login: self.can_login,
164 replication: self.replication,
165 bypass_rls: self.bypass_rls,
166 conn_limit: self.conn_limit,
167 password: match self.password {
168 Some(p) => Some(Cow::Borrowed(p)),
169 None => None,
170 },
171 valid_until: match self.valid_until {
172 Some(d) => Some(Cow::Borrowed(d)),
173 None => None,
174 },
175 }
176 }
177}
178
179impl Default for RoleDef {
180 fn default() -> Self {
181 Self::new("")
182 }
183}
184
185#[derive(Clone, Debug, PartialEq, Eq)]
191#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
192#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
193pub struct Role {
194 #[cfg_attr(feature = "serde", serde(deserialize_with = "cow_from_string"))]
196 pub name: Cow<'static, str>,
197
198 #[cfg_attr(
200 feature = "serde",
201 serde(default, skip_serializing_if = "Option::is_none")
202 )]
203 pub superuser: Option<bool>,
204
205 #[cfg_attr(
207 feature = "serde",
208 serde(default, skip_serializing_if = "Option::is_none")
209 )]
210 pub create_db: Option<bool>,
211
212 #[cfg_attr(
214 feature = "serde",
215 serde(default, skip_serializing_if = "Option::is_none")
216 )]
217 pub create_role: Option<bool>,
218
219 #[cfg_attr(
221 feature = "serde",
222 serde(default, skip_serializing_if = "Option::is_none")
223 )]
224 pub inherit: Option<bool>,
225
226 #[cfg_attr(
228 feature = "serde",
229 serde(default, skip_serializing_if = "Option::is_none")
230 )]
231 pub can_login: Option<bool>,
232
233 #[cfg_attr(
235 feature = "serde",
236 serde(default, skip_serializing_if = "Option::is_none")
237 )]
238 pub replication: Option<bool>,
239
240 #[cfg_attr(
242 feature = "serde",
243 serde(default, skip_serializing_if = "Option::is_none")
244 )]
245 pub bypass_rls: Option<bool>,
246
247 #[cfg_attr(
249 feature = "serde",
250 serde(default, skip_serializing_if = "Option::is_none")
251 )]
252 pub conn_limit: Option<i32>,
253
254 #[cfg_attr(
256 feature = "serde",
257 serde(
258 default,
259 skip_serializing_if = "Option::is_none",
260 deserialize_with = "cow_option_from_string"
261 )
262 )]
263 pub password: Option<Cow<'static, str>>,
264
265 #[cfg_attr(
267 feature = "serde",
268 serde(
269 default,
270 skip_serializing_if = "Option::is_none",
271 deserialize_with = "cow_option_from_string"
272 )
273 )]
274 pub valid_until: Option<Cow<'static, str>>,
275}
276
277impl Role {
278 #[must_use]
280 pub fn new(name: impl Into<Cow<'static, str>>) -> Self {
281 Self {
282 name: name.into(),
283 superuser: None,
284 create_db: None,
285 create_role: None,
286 inherit: None,
287 can_login: None,
288 replication: None,
289 bypass_rls: None,
290 conn_limit: None,
291 password: None,
292 valid_until: None,
293 }
294 }
295
296 #[inline]
298 #[must_use]
299 pub fn name(&self) -> &str {
300 &self.name
301 }
302}
303
304impl Default for Role {
305 fn default() -> Self {
306 Self::new("")
307 }
308}
309
310impl From<RoleDef> for Role {
311 fn from(def: RoleDef) -> Self {
312 def.into_role()
313 }
314}
315
316#[cfg(test)]
317mod tests {
318 use super::*;
319
320 #[test]
321 fn test_const_role_def() {
322 const ROLE: RoleDef = RoleDef::new("app_user")
323 .create_db(true)
324 .create_role(true)
325 .can_login(true);
326
327 assert_eq!(ROLE.name, "app_user");
328 assert_eq!(ROLE.create_db, Some(true));
329 assert_eq!(ROLE.create_role, Some(true));
330 assert_eq!(ROLE.can_login, Some(true));
331 }
332
333 #[test]
334 fn test_role_def_to_role() {
335 const DEF: RoleDef = RoleDef::new("admin").superuser(true).create_db(true);
336 let role = DEF.into_role();
337 assert_eq!(role.name(), "admin");
338 assert_eq!(role.superuser, Some(true));
339 assert_eq!(role.create_db, Some(true));
340 }
341
342 #[test]
343 fn test_role_with_conn_limit() {
344 const ROLE: RoleDef = RoleDef::new("limited_user").conn_limit(5).can_login(true);
345 let role = ROLE.into_role();
346 assert_eq!(role.conn_limit, Some(5));
347 }
348}