use osproxy_core::PrincipalId;
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Principal {
id: PrincipalId,
attrs: Vec<PrincipalAttr>,
}
impl Principal {
#[must_use]
pub fn new(id: PrincipalId) -> Self {
Self {
id,
attrs: Vec::new(),
}
}
#[must_use]
pub fn with_attr(mut self, attr: PrincipalAttr) -> Self {
self.attrs.push(attr);
self
}
#[must_use]
pub fn id(&self) -> &PrincipalId {
&self.id
}
#[must_use]
pub fn attr(&self, key: &str) -> Option<&str> {
self.attrs
.iter()
.find(|a| a.key == key)
.map(|a| a.value.as_str())
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct PrincipalAttr {
pub key: String,
pub value: String,
}
impl PrincipalAttr {
pub fn new(key: impl Into<String>, value: impl Into<String>) -> Self {
Self {
key: key.into(),
value: value.into(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn attributes_are_looked_up_by_key() {
let p = Principal::new(PrincipalId::from("u-1"))
.with_attr(PrincipalAttr::new("tenant", "acme"))
.with_attr(PrincipalAttr::new("region", "eu"));
assert_eq!(p.attr("tenant"), Some("acme"));
assert_eq!(p.attr("region"), Some("eu"));
assert_eq!(p.attr("nope"), None);
assert_eq!(p.id().as_str(), "u-1");
}
}