pub const ROLE_HIERARCHY: &[&str] =
&["public", "follower", "supporter", "contributor", "moderator", "leader"];
pub fn role_level(role: &str) -> Option<usize> {
ROLE_HIERARCHY.iter().position(|&r| r == role)
}
pub fn expand_roles(highest_roles: &[Box<str>]) -> String {
if highest_roles.is_empty() {
return String::new();
}
let mut highest_idx: Option<usize> = None;
for role in highest_roles {
if let Some(idx) = ROLE_HIERARCHY.iter().position(|&r| r == role.as_ref()) {
highest_idx = Some(highest_idx.map_or(idx, |h| h.max(idx)));
}
}
match highest_idx {
Some(idx) => ROLE_HIERARCHY[..=idx].join(","),
None => String::new(),
}
}
pub fn expand_roles_preserving_extras(roles: &[Box<str>]) -> String {
let mut result = expand_roles(roles);
for role in roles {
if role_level(role).is_some() {
continue;
}
if result.split(',').any(|r| r == role.as_ref()) {
continue;
}
if !result.is_empty() {
result.push(',');
}
result.push_str(role);
}
result
}
#[cfg(test)]
mod tests {
use super::*;
const LEADER_EXPANDED: &str = "public,follower,supporter,contributor,moderator,leader";
#[test]
fn test_expand_roles_empty() {
assert_eq!(expand_roles(&[]), "");
}
#[test]
fn test_expand_roles_single() {
assert_eq!(expand_roles(&["public".into()]), "public");
assert_eq!(expand_roles(&["follower".into()]), "public,follower");
assert_eq!(
expand_roles(&["moderator".into()]),
"public,follower,supporter,contributor,moderator"
);
assert_eq!(expand_roles(&["leader".into()]), LEADER_EXPANDED);
}
#[test]
fn test_expand_roles_multiple() {
assert_eq!(
expand_roles(&["contributor".into(), "moderator".into()]),
"public,follower,supporter,contributor,moderator"
);
assert_eq!(expand_roles(&["public".into(), "leader".into()]), LEADER_EXPANDED);
}
#[test]
fn test_expand_roles_unknown() {
assert_eq!(expand_roles(&["unknown".into()]), "");
assert_eq!(
expand_roles(&["unknown".into(), "contributor".into()]),
"public,follower,supporter,contributor"
);
}
#[test]
fn test_expand_roles_preserving_extras() {
assert_eq!(expand_roles(&["leader".into(), "SADM".into()]), LEADER_EXPANDED);
assert_eq!(
expand_roles_preserving_extras(&["leader".into(), "SADM".into()]),
format!("{LEADER_EXPANDED},SADM")
);
assert_eq!(
expand_roles_preserving_extras(&["moderator".into()]),
expand_roles(&["moderator".into()])
);
assert_eq!(expand_roles_preserving_extras(&["SADM".into()]), "SADM");
assert_eq!(expand_roles_preserving_extras(&[]), "");
assert_eq!(
expand_roles_preserving_extras(&["SADM".into(), "SADM".into(), "OPS".into()]),
"SADM,OPS"
);
assert_eq!(
expand_roles_preserving_extras(&["leader".into(), "leader".into()]),
LEADER_EXPANDED
);
}
#[test]
fn test_role_level() {
assert_eq!(role_level("public"), Some(0));
assert_eq!(role_level("follower"), Some(1));
assert_eq!(role_level("moderator"), Some(4));
assert_eq!(role_level("leader"), Some(5));
assert_eq!(role_level("unknown"), None);
}
}