use crate::contracts::{BindingKind, BindingReference, ExtensionMetadata};
use crate::error::FrameworkError;
use knowledge_base_models::{EntityTypeId, PropertyId};
use std::collections::BTreeMap;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum BindingValue {
EntityType(EntityTypeId),
Property(PropertyId),
}
impl BindingValue {
pub const fn kind(&self) -> BindingKind {
match self {
Self::EntityType(_) => BindingKind::EntityType,
Self::Property(_) => BindingKind::Property,
}
}
}
#[derive(Clone, Debug, Default)]
pub struct ResolvedBindings {
pub(crate) values: BTreeMap<BindingReference, BindingValue>,
}
impl ResolvedBindings {
pub fn get(&self, extension: &ExtensionMetadata, reference: &BindingReference) -> Result<&BindingValue, FrameworkError> {
if reference.extension_id() != &extension.id && !extension.dependencies.iter().any(|dependency| dependency.id == *reference.extension_id()) {
return Err(FrameworkError::InaccessibleBinding {
extension: extension.id.clone(),
binding: reference.clone(),
});
}
self.values.get(reference).ok_or_else(|| FrameworkError::MissingBinding(reference.clone()))
}
pub fn entity_type(&self, extension: &ExtensionMetadata, reference: &BindingReference) -> Result<&EntityTypeId, FrameworkError> {
match self.get(extension, reference)? {
BindingValue::EntityType(id) => Ok(id),
value => Err(FrameworkError::BindingKindMismatch {
binding: reference.clone(),
expected: BindingKind::EntityType,
actual: value.kind(),
}),
}
}
pub fn property(&self, extension: &ExtensionMetadata, reference: &BindingReference) -> Result<&PropertyId, FrameworkError> {
match self.get(extension, reference)? {
BindingValue::Property(id) => Ok(id),
value => Err(FrameworkError::BindingKindMismatch {
binding: reference.clone(),
expected: BindingKind::Property,
actual: value.kind(),
}),
}
}
}