drizzle_types/postgres/ddl/
policy.rs1#[cfg(feature = "std")]
8use std::borrow::Cow;
9
10#[cfg(all(feature = "alloc", not(feature = "std")))]
11use alloc::borrow::Cow;
12
13#[cfg(feature = "serde")]
14use crate::serde_helpers::{cow_from_string, cow_option_from_string, cow_option_vec_from_strings};
15
16#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22pub struct PolicyDef {
23 pub schema: &'static str,
25 pub table: &'static str,
27 pub name: &'static str,
29 pub as_clause: Option<&'static str>,
31 pub for_clause: Option<&'static str>,
33 pub to: Option<&'static [&'static str]>,
35 pub using: Option<&'static str>,
37 pub with_check: Option<&'static str>,
39}
40
41impl PolicyDef {
42 #[must_use]
44 pub const fn new(schema: &'static str, table: &'static str, name: &'static str) -> Self {
45 Self {
46 schema,
47 table,
48 name,
49 as_clause: None,
50 for_clause: None,
51 to: None,
52 using: None,
53 with_check: None,
54 }
55 }
56
57 #[must_use]
59 pub const fn as_clause(self, clause: &'static str) -> Self {
60 Self {
61 as_clause: Some(clause),
62 ..self
63 }
64 }
65
66 #[must_use]
68 pub const fn for_clause(self, clause: &'static str) -> Self {
69 Self {
70 for_clause: Some(clause),
71 ..self
72 }
73 }
74
75 #[must_use]
77 pub const fn to(self, roles: &'static [&'static str]) -> Self {
78 Self {
79 to: Some(roles),
80 ..self
81 }
82 }
83
84 #[must_use]
86 pub const fn using(self, expr: &'static str) -> Self {
87 Self {
88 using: Some(expr),
89 ..self
90 }
91 }
92
93 #[must_use]
95 pub const fn with_check(self, expr: &'static str) -> Self {
96 Self {
97 with_check: Some(expr),
98 ..self
99 }
100 }
101
102 #[must_use]
104 pub const fn into_policy(self) -> Policy {
105 Policy {
106 schema: Cow::Borrowed(self.schema),
107 table: Cow::Borrowed(self.table),
108 name: Cow::Borrowed(self.name),
109 as_clause: match self.as_clause {
110 Some(s) => Some(Cow::Borrowed(s)),
111 None => None,
112 },
113 for_clause: match self.for_clause {
114 Some(s) => Some(Cow::Borrowed(s)),
115 None => None,
116 },
117 to: match self.to {
118 Some(roles) => Some(Cow::Borrowed(roles)),
119 None => None,
120 },
121 using: match self.using {
122 Some(s) => Some(Cow::Borrowed(s)),
123 None => None,
124 },
125 with_check: match self.with_check {
126 Some(s) => Some(Cow::Borrowed(s)),
127 None => None,
128 },
129 }
130 }
131}
132
133#[derive(Clone, Debug, PartialEq, Eq)]
139#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
140#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
141pub struct Policy {
142 #[cfg_attr(feature = "serde", serde(deserialize_with = "cow_from_string"))]
144 pub schema: Cow<'static, str>,
145
146 #[cfg_attr(feature = "serde", serde(deserialize_with = "cow_from_string"))]
148 pub table: Cow<'static, str>,
149
150 #[cfg_attr(feature = "serde", serde(deserialize_with = "cow_from_string"))]
152 pub name: Cow<'static, str>,
153
154 #[cfg_attr(
156 feature = "serde",
157 serde(
158 rename = "as",
159 skip_serializing_if = "Option::is_none",
160 deserialize_with = "cow_option_from_string"
161 )
162 )]
163 pub as_clause: Option<Cow<'static, str>>,
164
165 #[cfg_attr(
167 feature = "serde",
168 serde(
169 rename = "for",
170 skip_serializing_if = "Option::is_none",
171 deserialize_with = "cow_option_from_string"
172 )
173 )]
174 pub for_clause: Option<Cow<'static, str>>,
175
176 #[cfg_attr(
178 feature = "serde",
179 serde(
180 skip_serializing_if = "Option::is_none",
181 deserialize_with = "cow_option_vec_from_strings"
182 )
183 )]
184 pub to: Option<Cow<'static, [&'static str]>>,
185
186 #[cfg_attr(
188 feature = "serde",
189 serde(
190 skip_serializing_if = "Option::is_none",
191 deserialize_with = "cow_option_from_string"
192 )
193 )]
194 pub using: Option<Cow<'static, str>>,
195
196 #[cfg_attr(
198 feature = "serde",
199 serde(
200 skip_serializing_if = "Option::is_none",
201 deserialize_with = "cow_option_from_string"
202 )
203 )]
204 pub with_check: Option<Cow<'static, str>>,
205}
206
207impl Policy {
208 #[must_use]
210 pub fn new(
211 schema: impl Into<Cow<'static, str>>,
212 table: impl Into<Cow<'static, str>>,
213 name: impl Into<Cow<'static, str>>,
214 ) -> Self {
215 Self {
216 schema: schema.into(),
217 table: table.into(),
218 name: name.into(),
219 as_clause: None,
220 for_clause: None,
221 to: None,
222 using: None,
223 with_check: None,
224 }
225 }
226
227 #[inline]
229 #[must_use]
230 pub fn schema(&self) -> &str {
231 &self.schema
232 }
233
234 #[inline]
236 #[must_use]
237 pub fn table(&self) -> &str {
238 &self.table
239 }
240
241 #[inline]
243 #[must_use]
244 pub fn name(&self) -> &str {
245 &self.name
246 }
247}
248
249impl From<PolicyDef> for Policy {
250 fn from(def: PolicyDef) -> Self {
251 def.into_policy()
252 }
253}
254
255#[cfg(test)]
256mod tests {
257 use super::*;
258
259 #[test]
260 fn test_const_policy_def() {
261 const POLICY: PolicyDef = PolicyDef::new("public", "users", "users_policy")
262 .for_clause("SELECT")
263 .using("user_id = current_user_id()");
264
265 assert_eq!(POLICY.schema, "public");
266 assert_eq!(POLICY.table, "users");
267 assert_eq!(POLICY.name, "users_policy");
268 }
269
270 #[test]
271 fn test_policy_def_to_policy() {
272 const DEF: PolicyDef = PolicyDef::new("public", "users", "policy");
273 let policy = DEF.into_policy();
274 assert_eq!(policy.schema(), "public");
275 assert_eq!(policy.table(), "users");
276 assert_eq!(policy.name(), "policy");
277 }
278}