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