1pub const ROLE_HIERARCHY: &[&str] =
16 &["public", "follower", "supporter", "contributor", "moderator", "leader"];
17
18pub fn role_level(role: &str) -> Option<usize> {
20 ROLE_HIERARCHY.iter().position(|&r| r == role)
21}
22
23pub fn expand_roles(highest_roles: &[Box<str>]) -> String {
37 if highest_roles.is_empty() {
38 return String::new();
39 }
40
41 let mut highest_idx: Option<usize> = None;
42 for role in highest_roles {
43 if let Some(idx) = ROLE_HIERARCHY.iter().position(|&r| r == role.as_ref()) {
44 highest_idx = Some(highest_idx.map_or(idx, |h| h.max(idx)));
45 }
46 }
47
48 match highest_idx {
50 Some(idx) => ROLE_HIERARCHY[..=idx].join(","),
51 None => String::new(),
52 }
53}
54
55pub fn expand_roles_preserving_extras(roles: &[Box<str>]) -> String {
69 let mut result = expand_roles(roles);
70 for role in roles {
71 if role_level(role).is_some() {
72 continue;
73 }
74 if result.split(',').any(|r| r == role.as_ref()) {
76 continue;
77 }
78 if !result.is_empty() {
79 result.push(',');
80 }
81 result.push_str(role);
82 }
83 result
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 const LEADER_EXPANDED: &str = "public,follower,supporter,contributor,moderator,leader";
91
92 #[test]
93 fn test_expand_roles_empty() {
94 assert_eq!(expand_roles(&[]), "");
95 }
96
97 #[test]
98 fn test_expand_roles_single() {
99 assert_eq!(expand_roles(&["public".into()]), "public");
100 assert_eq!(expand_roles(&["follower".into()]), "public,follower");
101 assert_eq!(
102 expand_roles(&["moderator".into()]),
103 "public,follower,supporter,contributor,moderator"
104 );
105 assert_eq!(expand_roles(&["leader".into()]), LEADER_EXPANDED);
106 }
107
108 #[test]
109 fn test_expand_roles_multiple() {
110 assert_eq!(
112 expand_roles(&["contributor".into(), "moderator".into()]),
113 "public,follower,supporter,contributor,moderator"
114 );
115 assert_eq!(expand_roles(&["public".into(), "leader".into()]), LEADER_EXPANDED);
116 }
117
118 #[test]
119 fn test_expand_roles_unknown() {
120 assert_eq!(expand_roles(&["unknown".into()]), "");
122 assert_eq!(
123 expand_roles(&["unknown".into(), "contributor".into()]),
124 "public,follower,supporter,contributor"
125 );
126 }
127
128 #[test]
129 fn test_expand_roles_preserving_extras() {
130 assert_eq!(expand_roles(&["leader".into(), "SADM".into()]), LEADER_EXPANDED);
133 assert_eq!(
134 expand_roles_preserving_extras(&["leader".into(), "SADM".into()]),
135 format!("{LEADER_EXPANDED},SADM")
136 );
137
138 assert_eq!(
140 expand_roles_preserving_extras(&["moderator".into()]),
141 expand_roles(&["moderator".into()])
142 );
143
144 assert_eq!(expand_roles_preserving_extras(&["SADM".into()]), "SADM");
146 assert_eq!(expand_roles_preserving_extras(&[]), "");
147
148 assert_eq!(
150 expand_roles_preserving_extras(&["SADM".into(), "SADM".into(), "OPS".into()]),
151 "SADM,OPS"
152 );
153 assert_eq!(
155 expand_roles_preserving_extras(&["leader".into(), "leader".into()]),
156 LEADER_EXPANDED
157 );
158 }
159
160 #[test]
161 fn test_role_level() {
162 assert_eq!(role_level("public"), Some(0));
163 assert_eq!(role_level("follower"), Some(1));
164 assert_eq!(role_level("moderator"), Some(4));
165 assert_eq!(role_level("leader"), Some(5));
166 assert_eq!(role_level("unknown"), None);
167 }
168}
169
170