use std::collections::BTreeSet;
pub fn principal_set<'a>(
name: Option<&'a str>,
user_id: Option<&'a str>,
groups: &'a [String],
) -> BTreeSet<&'a str> {
let mut set: BTreeSet<&'a str> = groups
.iter()
.map(String::as_str)
.filter(|s| !s.is_empty())
.collect();
for v in [name, user_id].into_iter().flatten() {
if !v.is_empty() {
set.insert(v);
}
}
set
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn principal_set_is_groups_union_name_union_user_id() {
let groups = vec!["eng".to_string(), "ops".to_string()];
let set = principal_set(Some("bob-laptop"), Some("b64u:BOB"), &groups);
let want: BTreeSet<&str> = ["eng", "ops", "bob-laptop", "b64u:BOB"].into();
assert_eq!(set, want);
}
#[test]
fn empty_components_are_skipped_and_absent_identity_is_default_deny() {
let groups = vec![String::new(), "eng".to_string()];
let set = principal_set(Some(""), None, &groups);
assert_eq!(set, BTreeSet::from(["eng"]));
assert!(principal_set(None, None, &[]).is_empty());
}
#[test]
fn pairing_mode_petname_is_a_principal() {
let set = principal_set(Some("carol"), None, &[]);
assert_eq!(set, BTreeSet::from(["carol"]));
}
}