use plexus_auth_core::ForwardPolicy;
use std::collections::HashMap;
use std::sync::Arc;
#[derive(Clone, Default)]
pub struct ForwardPolicyRegistry {
inner: HashMap<String, Arc<dyn ForwardPolicy>>,
}
impl ForwardPolicyRegistry {
pub fn new() -> Self {
Self {
inner: HashMap::new(),
}
}
pub fn register(&mut self, callee_ns: impl Into<String>, policy: Arc<dyn ForwardPolicy>) {
self.inner.insert(callee_ns.into(), policy);
}
pub fn get(&self, callee_ns: &str) -> Option<Arc<dyn ForwardPolicy>> {
self.inner.get(callee_ns).cloned()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn len(&self) -> usize {
self.inner.len()
}
}
impl std::fmt::Debug for ForwardPolicyRegistry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut keys: Vec<&String> = self.inner.keys().collect();
keys.sort();
f.debug_struct("ForwardPolicyRegistry")
.field("entries", &keys)
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use plexus_auth_core::{Anonymous, IdentityOnly, PassThrough};
#[test]
fn empty_registry_returns_none_for_any_key() {
let r = ForwardPolicyRegistry::new();
assert!(r.is_empty());
assert!(r.get("solar").is_none());
assert!(r.get("nonexistent").is_none());
}
#[test]
fn register_then_lookup_returns_arc() {
let mut r = ForwardPolicyRegistry::new();
r.register("solar", Arc::new(PassThrough));
r.register("echo", Arc::new(Anonymous));
assert_eq!(r.len(), 2);
assert_eq!(r.get("solar").unwrap().name().as_str(), "pass_through");
assert_eq!(r.get("echo").unwrap().name().as_str(), "anonymous");
assert!(r.get("missing").is_none());
}
#[test]
fn register_replaces_existing_entry() {
let mut r = ForwardPolicyRegistry::new();
r.register("solar", Arc::new(IdentityOnly));
r.register("solar", Arc::new(PassThrough));
assert_eq!(r.len(), 1);
assert_eq!(r.get("solar").unwrap().name().as_str(), "pass_through");
}
#[test]
fn default_is_empty() {
let r = ForwardPolicyRegistry::default();
assert!(r.is_empty());
}
#[test]
fn debug_lists_keys_alphabetically() {
let mut r = ForwardPolicyRegistry::new();
r.register("solar", Arc::new(PassThrough));
r.register("echo", Arc::new(Anonymous));
let dbg = format!("{:?}", r);
assert!(dbg.contains("echo"));
assert!(dbg.contains("solar"));
let echo_pos = dbg.find("echo").unwrap();
let solar_pos = dbg.find("solar").unwrap();
assert!(echo_pos < solar_pos);
}
}