drizzle_types/postgres/ddl/
privilege.rs1use crate::alloc_prelude::*;
7
8#[cfg(feature = "serde")]
9use crate::serde_helpers::cow_from_string;
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18#[cfg_attr(feature = "serde", serde(rename_all = "SCREAMING_SNAKE_CASE"))]
19pub enum PrivilegeType {
20 #[default]
22 All,
23 Select,
25 Insert,
27 Update,
29 Delete,
31 Truncate,
33 References,
35 Trigger,
37}
38
39impl PrivilegeType {
40 #[must_use]
42 pub const fn as_sql(&self) -> &'static str {
43 match self {
44 Self::All => "ALL",
45 Self::Select => "SELECT",
46 Self::Insert => "INSERT",
47 Self::Update => "UPDATE",
48 Self::Delete => "DELETE",
49 Self::Truncate => "TRUNCATE",
50 Self::References => "REFERENCES",
51 Self::Trigger => "TRIGGER",
52 }
53 }
54
55 #[must_use]
58 pub fn from_sql(s: &str) -> Option<Self> {
59 match s.to_uppercase().as_str() {
60 "ALL" => Some(Self::All),
61 "SELECT" => Some(Self::Select),
62 "INSERT" => Some(Self::Insert),
63 "UPDATE" => Some(Self::Update),
64 "DELETE" => Some(Self::Delete),
65 "TRUNCATE" => Some(Self::Truncate),
66 "REFERENCES" => Some(Self::References),
67 "TRIGGER" => Some(Self::Trigger),
68 _ => None,
69 }
70 }
71}
72
73#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
79pub struct PrivilegeDef {
80 pub grantor: &'static str,
82 pub grantee: &'static str,
84 pub schema: &'static str,
86 pub table: &'static str,
88 pub privilege_type: PrivilegeType,
90 pub is_grantable: bool,
92}
93
94impl PrivilegeDef {
95 #[must_use]
97 pub const fn new(
98 schema: &'static str,
99 table: &'static str,
100 grantee: &'static str,
101 privilege_type: PrivilegeType,
102 ) -> Self {
103 Self {
104 grantor: "",
105 grantee,
106 schema,
107 table,
108 privilege_type,
109 is_grantable: false,
110 }
111 }
112
113 #[must_use]
115 pub const fn grantor(self, grantor: &'static str) -> Self {
116 Self { grantor, ..self }
117 }
118
119 #[must_use]
121 pub const fn grantable(self) -> Self {
122 Self {
123 is_grantable: true,
124 ..self
125 }
126 }
127
128 #[must_use]
130 pub const fn into_privilege(self) -> Privilege {
131 Privilege {
132 grantor: Cow::Borrowed(self.grantor),
133 grantee: Cow::Borrowed(self.grantee),
134 schema: Cow::Borrowed(self.schema),
135 table: Cow::Borrowed(self.table),
136 privilege_type: self.privilege_type,
137 is_grantable: self.is_grantable,
138 }
139 }
140}
141
142impl Default for PrivilegeDef {
143 fn default() -> Self {
144 Self::new("public", "", "", PrivilegeType::All)
145 }
146}
147
148#[derive(Clone, Debug, PartialEq, Eq)]
154#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
155#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
156pub struct Privilege {
157 #[cfg_attr(feature = "serde", serde(deserialize_with = "cow_from_string"))]
159 pub grantor: Cow<'static, str>,
160
161 #[cfg_attr(feature = "serde", serde(deserialize_with = "cow_from_string"))]
163 pub grantee: Cow<'static, str>,
164
165 #[cfg_attr(feature = "serde", serde(deserialize_with = "cow_from_string"))]
167 pub schema: Cow<'static, str>,
168
169 #[cfg_attr(feature = "serde", serde(deserialize_with = "cow_from_string"))]
171 pub table: Cow<'static, str>,
172
173 #[cfg_attr(feature = "serde", serde(rename = "type"))]
175 pub privilege_type: PrivilegeType,
176
177 #[cfg_attr(feature = "serde", serde(default))]
179 pub is_grantable: bool,
180}
181
182impl Privilege {
183 #[must_use]
185 pub fn new(
186 schema: impl Into<Cow<'static, str>>,
187 table: impl Into<Cow<'static, str>>,
188 grantee: impl Into<Cow<'static, str>>,
189 privilege_type: PrivilegeType,
190 ) -> Self {
191 Self {
192 grantor: Cow::Borrowed(""),
193 grantee: grantee.into(),
194 schema: schema.into(),
195 table: table.into(),
196 privilege_type,
197 is_grantable: false,
198 }
199 }
200
201 #[inline]
203 #[must_use]
204 pub fn schema(&self) -> &str {
205 &self.schema
206 }
207
208 #[inline]
210 #[must_use]
211 pub fn table(&self) -> &str {
212 &self.table
213 }
214
215 #[inline]
217 #[must_use]
218 pub fn grantee(&self) -> &str {
219 &self.grantee
220 }
221
222 #[inline]
224 #[must_use]
225 pub fn grantor(&self) -> &str {
226 &self.grantor
227 }
228}
229
230impl Default for Privilege {
231 fn default() -> Self {
232 Self::new("public", "", "", PrivilegeType::All)
233 }
234}
235
236impl From<PrivilegeDef> for Privilege {
237 fn from(def: PrivilegeDef) -> Self {
238 def.into_privilege()
239 }
240}
241
242#[cfg(test)]
243mod tests {
244 use super::*;
245
246 #[test]
247 fn test_const_privilege_def() {
248 const PRIV: PrivilegeDef =
249 PrivilegeDef::new("public", "users", "app_user", PrivilegeType::Select)
250 .grantor("admin")
251 .grantable();
252
253 assert_eq!(PRIV.schema, "public");
254 assert_eq!(PRIV.table, "users");
255 assert_eq!(PRIV.grantee, "app_user");
256 assert_eq!(PRIV.grantor, "admin");
257 assert_eq!(PRIV.privilege_type, PrivilegeType::Select);
258 const {
259 assert!(PRIV.is_grantable);
260 }
261 }
262
263 #[test]
264 fn test_privilege_def_to_privilege() {
265 const DEF: PrivilegeDef =
266 PrivilegeDef::new("public", "users", "reader", PrivilegeType::Select);
267 let priv_ = DEF.into_privilege();
268 assert_eq!(priv_.schema(), "public");
269 assert_eq!(priv_.table(), "users");
270 assert_eq!(priv_.grantee(), "reader");
271 }
272
273 #[test]
274 fn test_privilege_type_sql() {
275 assert_eq!(PrivilegeType::Select.as_sql(), "SELECT");
276 assert_eq!(PrivilegeType::All.as_sql(), "ALL");
277 assert_eq!(PrivilegeType::Truncate.as_sql(), "TRUNCATE");
278 }
279}