featherdb_core/
permissions.rs1use serde::{Deserialize, Deserializer, Serialize, Serializer};
7use std::fmt;
8
9bitflags::bitflags! {
10 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
32 pub struct Permissions: u8 {
33 const SELECT = 0b0001;
35 const INSERT = 0b0010;
37 const UPDATE = 0b0100;
39 const DELETE = 0b1000;
41 const ALL = Self::SELECT.bits() | Self::INSERT.bits() |
43 Self::UPDATE.bits() | Self::DELETE.bits();
44 }
45}
46
47impl Permissions {
48 pub fn from_names<S: AsRef<str>>(names: &[S]) -> Result<Self, String> {
63 let mut perms = Permissions::empty();
64 for name in names {
65 let name_upper = name.as_ref().to_uppercase();
66 match name_upper.as_str() {
67 "SELECT" => perms |= Permissions::SELECT,
68 "INSERT" => perms |= Permissions::INSERT,
69 "UPDATE" => perms |= Permissions::UPDATE,
70 "DELETE" => perms |= Permissions::DELETE,
71 "ALL" => perms |= Permissions::ALL,
72 _ => return Err(format!("Unknown permission: {}", name.as_ref())),
73 }
74 }
75 Ok(perms)
76 }
77
78 pub fn to_names(&self) -> Vec<&'static str> {
91 let mut names = Vec::new();
92 if self.contains(Permissions::SELECT) {
93 names.push("SELECT");
94 }
95 if self.contains(Permissions::INSERT) {
96 names.push("INSERT");
97 }
98 if self.contains(Permissions::UPDATE) {
99 names.push("UPDATE");
100 }
101 if self.contains(Permissions::DELETE) {
102 names.push("DELETE");
103 }
104 names
105 }
106
107 pub fn description(&self) -> String {
109 if *self == Permissions::ALL {
110 return "ALL".to_string();
111 }
112 if self.is_empty() {
113 return "NONE".to_string();
114 }
115 self.to_names().join(", ")
116 }
117}
118
119impl Default for Permissions {
120 fn default() -> Self {
121 Permissions::empty()
122 }
123}
124
125impl fmt::Display for Permissions {
126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 write!(f, "{}", self.description())
128 }
129}
130
131impl Serialize for Permissions {
133 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
134 where
135 S: Serializer,
136 {
137 serializer.serialize_u8(self.bits())
138 }
139}
140
141impl<'de> Deserialize<'de> for Permissions {
142 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
143 where
144 D: Deserializer<'de>,
145 {
146 let bits = u8::deserialize(deserializer)?;
147 Permissions::from_bits(bits)
148 .ok_or_else(|| serde::de::Error::custom(format!("Invalid permission bits: {}", bits)))
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155
156 #[test]
157 fn test_permissions_individual() {
158 assert_eq!(Permissions::SELECT.bits(), 0b0001);
159 assert_eq!(Permissions::INSERT.bits(), 0b0010);
160 assert_eq!(Permissions::UPDATE.bits(), 0b0100);
161 assert_eq!(Permissions::DELETE.bits(), 0b1000);
162 }
163
164 #[test]
165 fn test_permissions_all() {
166 let all = Permissions::ALL;
167 assert!(all.contains(Permissions::SELECT));
168 assert!(all.contains(Permissions::INSERT));
169 assert!(all.contains(Permissions::UPDATE));
170 assert!(all.contains(Permissions::DELETE));
171 assert_eq!(all.bits(), 0b1111);
172 }
173
174 #[test]
175 fn test_permissions_combine() {
176 let perms = Permissions::SELECT | Permissions::INSERT;
177 assert!(perms.contains(Permissions::SELECT));
178 assert!(perms.contains(Permissions::INSERT));
179 assert!(!perms.contains(Permissions::UPDATE));
180 assert!(!perms.contains(Permissions::DELETE));
181 }
182
183 #[test]
184 fn test_permissions_from_names() {
185 let perms = Permissions::from_names(&["SELECT", "INSERT"]).unwrap();
186 assert!(perms.contains(Permissions::SELECT));
187 assert!(perms.contains(Permissions::INSERT));
188 assert!(!perms.contains(Permissions::UPDATE));
189
190 let perms = Permissions::from_names(&["select", "DELETE"]).unwrap();
192 assert!(perms.contains(Permissions::SELECT));
193 assert!(perms.contains(Permissions::DELETE));
194
195 let perms = Permissions::from_names(&["ALL"]).unwrap();
197 assert_eq!(perms, Permissions::ALL);
198
199 let result = Permissions::from_names(&["INVALID"]);
201 assert!(result.is_err());
202 }
203
204 #[test]
205 fn test_permissions_to_names() {
206 let perms = Permissions::SELECT | Permissions::DELETE;
207 let names = perms.to_names();
208 assert_eq!(names.len(), 2);
209 assert!(names.contains(&"SELECT"));
210 assert!(names.contains(&"DELETE"));
211
212 let empty = Permissions::empty();
213 assert!(empty.to_names().is_empty());
214 }
215
216 #[test]
217 fn test_permissions_display() {
218 assert_eq!(Permissions::ALL.to_string(), "ALL");
219 assert_eq!(Permissions::empty().to_string(), "NONE");
220 assert_eq!(Permissions::SELECT.to_string(), "SELECT");
221 assert_eq!(
222 (Permissions::SELECT | Permissions::INSERT).to_string(),
223 "SELECT, INSERT"
224 );
225 }
226
227 #[test]
228 fn test_permissions_default() {
229 let perms = Permissions::default();
230 assert!(perms.is_empty());
231 }
232
233 #[test]
234 fn test_permissions_serialization() {
235 let perms = Permissions::SELECT | Permissions::UPDATE;
236 let json = serde_json::to_string(&perms).unwrap();
237 assert_eq!(json, "5");
239 let deserialized: Permissions = serde_json::from_str(&json).unwrap();
240 assert_eq!(perms, deserialized);
241 }
242
243 #[test]
244 fn test_permissions_remove() {
245 let mut perms = Permissions::ALL;
246 perms.remove(Permissions::DELETE);
247 assert!(perms.contains(Permissions::SELECT));
248 assert!(perms.contains(Permissions::INSERT));
249 assert!(perms.contains(Permissions::UPDATE));
250 assert!(!perms.contains(Permissions::DELETE));
251 }
252}