1use std::any::Any;
16use std::fmt::Debug;
17use std::sync::Arc;
18
19use crate::UserInfoRef;
20
21pub trait UserInfo: Debug + Sync + Send {
22 fn as_any(&self) -> &dyn Any;
23 fn username(&self) -> &str;
24
25 fn is_admin(&self) -> bool {
26 false
27 }
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
32pub enum PermissionMode {
33 #[default]
34 ReadWrite,
35 ReadOnly,
36 WriteOnly,
37}
38
39impl PermissionMode {
40 pub fn from_str(s: &str) -> Option<Self> {
48 match s.to_lowercase().as_str() {
49 "readwrite" | "read_write" | "rw" => Some(PermissionMode::ReadWrite),
50 "readonly" | "read_only" | "ro" => Some(PermissionMode::ReadOnly),
51 "writeonly" | "write_only" | "wo" => Some(PermissionMode::WriteOnly),
52 _ => None,
53 }
54 }
55
56 pub fn as_str(&self) -> &'static str {
62 match self {
63 PermissionMode::ReadWrite => "rw",
64 PermissionMode::ReadOnly => "ro",
65 PermissionMode::WriteOnly => "wo",
66 }
67 }
68
69 pub fn can_read(&self) -> bool {
71 matches!(self, PermissionMode::ReadWrite | PermissionMode::ReadOnly)
72 }
73
74 pub fn can_write(&self) -> bool {
76 matches!(self, PermissionMode::ReadWrite | PermissionMode::WriteOnly)
77 }
78}
79
80impl std::fmt::Display for PermissionMode {
81 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 write!(f, "{}", self.as_str())
83 }
84}
85
86#[derive(Debug)]
87pub(crate) struct DefaultUserInfo {
88 username: String,
89 permission_mode: PermissionMode,
90}
91
92impl DefaultUserInfo {
93 pub(crate) fn with_name(username: impl Into<String>) -> UserInfoRef {
94 Self::with_name_and_permission(username, PermissionMode::default())
95 }
96
97 pub(crate) fn with_name_and_permission(
99 username: impl Into<String>,
100 permission_mode: PermissionMode,
101 ) -> UserInfoRef {
102 Arc::new(Self {
103 username: username.into(),
104 permission_mode,
105 })
106 }
107
108 pub(crate) fn permission_mode(&self) -> &PermissionMode {
109 &self.permission_mode
110 }
111}
112
113impl UserInfo for DefaultUserInfo {
114 fn as_any(&self) -> &dyn Any {
115 self
116 }
117
118 fn username(&self) -> &str {
119 self.username.as_str()
120 }
121}
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn test_permission_mode_from_str() {
128 assert_eq!(
130 PermissionMode::from_str("readwrite"),
131 Some(PermissionMode::ReadWrite)
132 );
133 assert_eq!(
134 PermissionMode::from_str("read_write"),
135 Some(PermissionMode::ReadWrite)
136 );
137 assert_eq!(
138 PermissionMode::from_str("rw"),
139 Some(PermissionMode::ReadWrite)
140 );
141 assert_eq!(
142 PermissionMode::from_str("ReadWrite"),
143 Some(PermissionMode::ReadWrite)
144 );
145 assert_eq!(
146 PermissionMode::from_str("RW"),
147 Some(PermissionMode::ReadWrite)
148 );
149
150 assert_eq!(
152 PermissionMode::from_str("readonly"),
153 Some(PermissionMode::ReadOnly)
154 );
155 assert_eq!(
156 PermissionMode::from_str("read_only"),
157 Some(PermissionMode::ReadOnly)
158 );
159 assert_eq!(
160 PermissionMode::from_str("ro"),
161 Some(PermissionMode::ReadOnly)
162 );
163 assert_eq!(
164 PermissionMode::from_str("ReadOnly"),
165 Some(PermissionMode::ReadOnly)
166 );
167 assert_eq!(
168 PermissionMode::from_str("RO"),
169 Some(PermissionMode::ReadOnly)
170 );
171
172 assert_eq!(
174 PermissionMode::from_str("writeonly"),
175 Some(PermissionMode::WriteOnly)
176 );
177 assert_eq!(
178 PermissionMode::from_str("write_only"),
179 Some(PermissionMode::WriteOnly)
180 );
181 assert_eq!(
182 PermissionMode::from_str("wo"),
183 Some(PermissionMode::WriteOnly)
184 );
185 assert_eq!(
186 PermissionMode::from_str("WriteOnly"),
187 Some(PermissionMode::WriteOnly)
188 );
189 assert_eq!(
190 PermissionMode::from_str("WO"),
191 Some(PermissionMode::WriteOnly)
192 );
193
194 for invalid in ["readonyl", "", "xyz"] {
195 assert_eq!(PermissionMode::from_str(invalid), None);
196 }
197 }
198
199 #[test]
200 fn test_permission_mode_as_str() {
201 assert_eq!(PermissionMode::ReadWrite.as_str(), "rw");
202 assert_eq!(PermissionMode::ReadOnly.as_str(), "ro");
203 assert_eq!(PermissionMode::WriteOnly.as_str(), "wo");
204 }
205
206 #[test]
207 fn test_permission_mode_default() {
208 assert_eq!(PermissionMode::default(), PermissionMode::ReadWrite);
209 }
210
211 #[test]
212 fn test_permission_mode_round_trip() {
213 let modes = [
214 PermissionMode::ReadWrite,
215 PermissionMode::ReadOnly,
216 PermissionMode::WriteOnly,
217 ];
218
219 for mode in modes {
220 let str_repr = mode.as_str();
221 let parsed = PermissionMode::from_str(str_repr);
222 assert_eq!(Some(mode), parsed);
223 }
224 }
225
226 #[test]
227 fn test_user_info_as_any() {
228 let user_info = DefaultUserInfo::with_name("test_user");
229 let any_ref = user_info.as_any();
230 assert!(any_ref.downcast_ref::<DefaultUserInfo>().is_some());
231 }
232}