use std::collections::HashSet;
use crate::{
ProviderName,
ProviderRegistryError,
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProviderDescriptor {
id: ProviderName,
aliases: Vec<ProviderName>,
priority: i32,
}
impl ProviderDescriptor {
#[inline]
pub fn new(id: &str) -> Result<Self, ProviderRegistryError> {
Ok(Self {
id: ProviderName::new(id)?,
aliases: Vec::new(),
priority: 0,
})
}
#[inline]
pub fn with_aliases(mut self, aliases: &[&str]) -> Result<Self, ProviderRegistryError> {
let aliases = aliases
.iter()
.map(|alias| ProviderName::new(alias))
.collect::<Result<Vec<_>, _>>()?;
validate_unique_names(&self.id, &aliases)?;
self.aliases = aliases;
Ok(self)
}
#[inline]
pub fn with_priority(mut self, priority: i32) -> Self {
self.priority = priority;
self
}
#[inline]
pub fn id(&self) -> &ProviderName {
&self.id
}
#[inline]
pub fn aliases(&self) -> &[ProviderName] {
&self.aliases
}
#[inline]
pub fn aliases_as_str(&self) -> Vec<&str> {
self.aliases.iter().map(ProviderName::as_str).collect()
}
#[inline]
pub fn priority(&self) -> i32 {
self.priority
}
#[inline]
pub(crate) fn names(&self) -> impl Iterator<Item = &ProviderName> {
std::iter::once(&self.id).chain(self.aliases.iter())
}
}
fn validate_unique_names(
id: &ProviderName,
aliases: &[ProviderName],
) -> Result<(), ProviderRegistryError> {
let mut names = HashSet::with_capacity(aliases.len() + 1);
names.insert(id.clone());
for alias in aliases {
if !names.insert(alias.clone()) {
return Err(ProviderRegistryError::DuplicateProviderName {
name: alias.clone(),
});
}
}
Ok(())
}