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