use std::collections::HashMap;
use crate::Label;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FieldRole {
Data,
Identifier,
Sensitive,
Managed,
}
#[derive(Debug, Clone, Copy)]
pub struct ResourceFieldDescriptor {
pub name: &'static str,
pub role: FieldRole,
}
#[derive(Debug, Clone)]
pub struct ResourceTypeDescriptor<L: Label> {
pub label: L,
pub fields: &'static [ResourceFieldDescriptor],
pub path_names: &'static [&'static str],
pub parent_label: Option<L>,
}
#[derive(Debug, Clone)]
pub struct ResourceRegistry<L: Label> {
by_label: HashMap<L, &'static ResourceTypeDescriptor<L>>,
}
impl<L: Label> ResourceRegistry<L> {
pub fn from_static(descriptors: &'static [ResourceTypeDescriptor<L>]) -> Self {
let by_label = descriptors.iter().map(|d| (d.label, d)).collect();
Self { by_label }
}
pub fn get(&self, label: L) -> Option<&&'static ResourceTypeDescriptor<L>> {
self.by_label.get(&label)
}
pub fn sensitive_field_names(&self, label: L) -> Vec<&'static str> {
self.by_label
.get(&label)
.map(|d| {
d.fields
.iter()
.filter(|f| f.role == FieldRole::Sensitive)
.map(|f| f.name)
.collect()
})
.unwrap_or_default()
}
pub fn has_sensitive_fields(&self, label: L) -> bool {
self.by_label
.get(&label)
.is_some_and(|d| d.fields.iter().any(|f| f.role == FieldRole::Sensitive))
}
pub fn managed_field_names(&self, label: L) -> Vec<&'static str> {
self.by_label
.get(&label)
.map(|d| {
d.fields
.iter()
.filter(|f| f.role == FieldRole::Managed)
.map(|f| f.name)
.collect()
})
.unwrap_or_default()
}
pub fn identifier_field_name(&self, label: L) -> Option<&'static str> {
self.by_label.get(&label).and_then(|d| {
d.fields
.iter()
.find(|f| f.role == FieldRole::Identifier)
.map(|f| f.name)
})
}
pub fn parent_label(&self, label: L) -> Option<L> {
self.by_label.get(&label).and_then(|d| d.parent_label)
}
pub fn path_names(&self, label: L) -> Option<&'static [&'static str]> {
self.by_label.get(&label).map(|d| d.path_names)
}
pub fn labels(&self) -> impl Iterator<Item = &L> {
self.by_label.keys()
}
}