use bitflags::bitflags;
use std::fmt;
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SmartPermissions: u8 {
const CREATE = 0b0000_0001;
const READ = 0b0000_0010;
const UPDATE = 0b0000_0100;
const DELETE = 0b0000_1000;
const SEARCH = 0b0001_0000;
}
}
impl SmartPermissions {
pub fn from_permission_str(s: &str) -> Option<Self> {
let mut perms = SmartPermissions::empty();
for ch in s.chars() {
match ch {
'c' => perms |= SmartPermissions::CREATE,
'r' => perms |= SmartPermissions::READ,
'u' => perms |= SmartPermissions::UPDATE,
'd' => perms |= SmartPermissions::DELETE,
's' => perms |= SmartPermissions::SEARCH,
_ => return None,
}
}
if perms.is_empty() { None } else { Some(perms) }
}
}
impl fmt::Display for SmartPermissions {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.contains(SmartPermissions::CREATE) {
write!(f, "c")?;
}
if self.contains(SmartPermissions::READ) {
write!(f, "r")?;
}
if self.contains(SmartPermissions::UPDATE) {
write!(f, "u")?;
}
if self.contains(SmartPermissions::DELETE) {
write!(f, "d")?;
}
if self.contains(SmartPermissions::SEARCH) {
write!(f, "s")?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_single_permissions() {
assert_eq!(
SmartPermissions::from_permission_str("r"),
Some(SmartPermissions::READ)
);
assert_eq!(
SmartPermissions::from_permission_str("c"),
Some(SmartPermissions::CREATE)
);
assert_eq!(
SmartPermissions::from_permission_str("s"),
Some(SmartPermissions::SEARCH)
);
}
#[test]
fn test_parse_combined_permissions() {
assert_eq!(
SmartPermissions::from_permission_str("rs"),
Some(SmartPermissions::READ | SmartPermissions::SEARCH)
);
assert_eq!(
SmartPermissions::from_permission_str("cruds"),
Some(
SmartPermissions::CREATE
| SmartPermissions::READ
| SmartPermissions::UPDATE
| SmartPermissions::DELETE
| SmartPermissions::SEARCH
)
);
}
#[test]
fn test_parse_invalid_permission() {
assert_eq!(SmartPermissions::from_permission_str("x"), None);
assert_eq!(SmartPermissions::from_permission_str("rz"), None);
assert_eq!(SmartPermissions::from_permission_str(""), None);
}
#[test]
fn test_display() {
let perms = SmartPermissions::READ | SmartPermissions::SEARCH;
assert_eq!(format!("{}", perms), "rs");
let all = SmartPermissions::CREATE
| SmartPermissions::READ
| SmartPermissions::UPDATE
| SmartPermissions::DELETE
| SmartPermissions::SEARCH;
assert_eq!(format!("{}", all), "cruds");
}
}