surql_parser/upstream/sql/
permission.rs1use crate::upstream::fmt::CoverStmts;
2use crate::upstream::sql::Expr;
3use surrealdb_types::{SqlFormat, ToSql, write_sql};
4#[derive(Clone, Debug, Default, PartialEq, Eq)]
5#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
6pub struct Permissions {
7 pub select: Permission,
8 pub create: Permission,
9 pub update: Permission,
10 pub delete: Permission,
11}
12impl Permissions {
13 pub fn none() -> Self {
14 Permissions {
15 select: Permission::None,
16 create: Permission::None,
17 update: Permission::None,
18 delete: Permission::None,
19 }
20 }
21 pub fn full() -> Self {
22 Permissions {
23 select: Permission::Full,
24 create: Permission::Full,
25 update: Permission::Full,
26 delete: Permission::Full,
27 }
28 }
29 pub fn is_none(&self) -> bool {
30 matches!(self.select, Permission::None)
31 && matches!(self.create, Permission::None)
32 && matches!(self.update, Permission::None)
33 && matches!(self.delete, Permission::None)
34 }
35 pub fn is_full(&self) -> bool {
36 matches!(self.select, Permission::Full)
37 && matches!(self.create, Permission::Full)
38 && matches!(self.update, Permission::Full)
39 && matches!(self.delete, Permission::Full)
40 }
41}
42#[derive(Clone, Copy, Eq, PartialEq, Debug)]
43pub enum PermissionKind {
44 Select,
45 Create,
46 Update,
47 Delete,
48}
49impl PermissionKind {
50 fn as_str(&self) -> &str {
51 match self {
52 PermissionKind::Select => "select",
53 PermissionKind::Create => "create",
54 PermissionKind::Update => "update",
55 PermissionKind::Delete => "delete",
56 }
57 }
58}
59impl surrealdb_types::ToSql for Permissions {
60 fn fmt_sql(&self, f: &mut String, fmt: surrealdb_types::SqlFormat) {
61 f.push_str("PERMISSIONS");
62 if self.is_none() {
63 f.push_str(" NONE");
64 return;
65 }
66 if self.is_full() {
67 f.push_str(" FULL");
68 return;
69 }
70 let mut lines = Vec::<(Vec<PermissionKind>, &Permission)>::new();
71 for (c, permission) in [
72 PermissionKind::Select,
73 PermissionKind::Create,
74 PermissionKind::Update,
75 PermissionKind::Delete,
76 ]
77 .into_iter()
78 .zip([&self.select, &self.create, &self.update, &self.delete])
79 {
80 if matches!(c, PermissionKind::Delete) && matches!(permission, Permission::Full) {
81 continue;
82 }
83 if let Some((existing, _)) = lines.iter_mut().find(|(_, p)| *p == permission) {
84 existing.push(c);
85 } else {
86 lines.push((vec![c], permission));
87 }
88 }
89 if fmt.is_pretty() {
90 f.push('\n');
91 let inner_fmt = fmt.increment();
92 inner_fmt.write_indent(f);
93 } else {
94 f.push(' ');
95 }
96 for (i, (kinds, permission)) in lines.into_iter().enumerate() {
97 if i > 0 {
98 if fmt.is_pretty() {
99 f.push(',');
100 f.push('\n');
101 let inner_fmt = fmt.increment();
102 inner_fmt.write_indent(f);
103 } else {
104 f.push_str(", ");
105 }
106 }
107 f.push_str("FOR ");
108 for (i, kind) in kinds.into_iter().enumerate() {
109 if i > 0 {
110 f.push_str(", ");
111 }
112 f.push_str(kind.as_str());
113 }
114 match permission {
115 Permission::Specific(v) if fmt.is_pretty() => {
116 f.push_str(" WHERE ");
117 CoverStmts(v).fmt_sql(f, fmt);
118 }
119 Permission::None => f.push_str(" NONE"),
120 Permission::Full => f.push_str(" FULL"),
121 Permission::Specific(v) => {
122 f.push_str(" WHERE ");
123 CoverStmts(v).fmt_sql(f, fmt);
124 }
125 }
126 }
127 }
128}
129impl From<Permissions> for crate::compat::catalog::Permissions {
130 fn from(v: Permissions) -> Self {
131 Self {
132 select: v.select.into(),
133 create: v.create.into(),
134 update: v.update.into(),
135 delete: v.delete.into(),
136 }
137 }
138}
139impl From<crate::compat::catalog::Permissions> for Permissions {
140 fn from(v: crate::compat::catalog::Permissions) -> Self {
141 Self {
142 select: v.select.into(),
143 create: v.create.into(),
144 update: v.update.into(),
145 delete: v.delete.into(),
146 }
147 }
148}
149#[derive(Clone, Debug, Default, PartialEq, Eq)]
150#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
151pub enum Permission {
152 None,
153 #[default]
154 Full,
155 Specific(Expr),
156}
157impl ToSql for Permission {
158 fn fmt_sql(&self, f: &mut String, sql_fmt: SqlFormat) {
159 match self {
160 Self::None => f.push_str("NONE"),
161 Self::Full => f.push_str("FULL"),
162 Self::Specific(v) => write_sql!(f, sql_fmt, "WHERE {}", CoverStmts(v)),
163 }
164 }
165}
166impl From<Permission> for crate::compat::catalog::Permission {
167 fn from(v: Permission) -> Self {
168 match v {
169 Permission::None => Self::None,
170 Permission::Full => Self::Full,
171 Permission::Specific(v) => Self::Specific(v.into()),
172 }
173 }
174}
175impl From<crate::compat::catalog::Permission> for Permission {
176 fn from(v: crate::compat::catalog::Permission) -> Self {
177 match v {
178 crate::compat::catalog::Permission::None => Self::None,
179 crate::compat::catalog::Permission::Full => Self::Full,
180 crate::compat::catalog::Permission::Specific(v) => Self::Specific(v.into()),
181 }
182 }
183}