use crate::core::resolver::{IResolver, orchestrator::LocaleEntry};
use crate::data::swap::IRegistryState;
#[derive(Default)]
pub struct AliasResolver {
next: Option<Box<dyn IResolver>>,
}
impl AliasResolver {
#[must_use]
pub fn new() -> Self {
Self::default()
}
}
impl IResolver for AliasResolver {
fn resolve(
&self,
tag: &str,
state: &dyn IRegistryState,
path: &mut Vec<String>,
) -> Option<LocaleEntry> {
if let Some(canonical_id) = state.resolve_alias(tag) {
path.push(format!("alias:{tag}->{canonical_id}"));
if state.get_profile(&canonical_id).is_some() {
path.push(canonical_id.clone());
return Some(LocaleEntry { id: canonical_id, resolution_path: path.clone() });
}
self.next.as_ref().and_then(|n| n.resolve(&canonical_id, state, path))
} else {
self.next.as_ref().and_then(|n| n.resolve(tag, state, path))
}
}
fn set_next(&mut self, next: Box<dyn IResolver>) {
self.next = Some(next);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::resolver::test_utils::*;
#[test]
fn test_alias_resolver_matches_and_returns() {
let mut mock_state = MockRegistryState::new();
mock_state
.expect_resolve_alias()
.with(mockall::predicate::eq("in"))
.returning(|_| Some("id".to_string()));
mock_state
.expect_get_profile()
.with(mockall::predicate::eq("id"))
.returning(|_| Some(create_stub("id")));
let resolver = AliasResolver::new();
let mut path = Vec::new();
let entry = resolver
.resolve("in", &mock_state, &mut path)
.expect("LMS-TEST: Alias resolution failed for valid tag");
assert_eq!(entry.id, "id");
assert_eq!(entry.resolution_path.len(), 2);
assert_eq!(entry.resolution_path[0], "alias:in->id");
assert_eq!(entry.resolution_path[1], "id");
}
#[test]
fn test_alias_resolver_delegates_non_aliases() {
let mut mock_state = MockRegistryState::new();
mock_state.expect_resolve_alias().with(mockall::predicate::eq("en-US")).returning(|_| None);
let mut next_resolver = MockNextResolver::new();
next_resolver.expect_resolve().withf(|tag, _, _| tag == "en-US").returning(|_, _, _| {
Some(LocaleEntry {
id: "en-US".to_string(),
resolution_path: vec!["en-US".to_string()],
})
});
let mut resolver = AliasResolver::new();
resolver.set_next(Box::new(next_resolver));
let mut path = Vec::new();
let entry = resolver
.resolve("en-US", &mock_state, &mut path)
.expect("LMS-TEST: Delegation failed for non-alias tag");
assert_eq!(entry.id, "en-US");
}
}