use super::SchemaType;
use crate::ast::{Entity, EntityType, EntityUID, Id, Name};
use smol_str::SmolStr;
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
pub trait Schema {
type EntityTypeDescription: EntityTypeDescription;
fn entity_type(&self, entity_type: &EntityType) -> Option<Self::EntityTypeDescription>;
fn action(&self, action: &EntityUID) -> Option<Arc<Entity>>;
fn entity_types_with_basename<'a>(
&'a self,
basename: &'a Id,
) -> Box<dyn Iterator<Item = EntityType> + 'a>;
}
#[derive(Debug, Clone)]
pub struct NoEntitiesSchema;
impl Schema for NoEntitiesSchema {
type EntityTypeDescription = NullEntityTypeDescription;
fn entity_type(&self, _entity_type: &EntityType) -> Option<NullEntityTypeDescription> {
None
}
fn action(&self, _action: &EntityUID) -> Option<Arc<Entity>> {
None
}
fn entity_types_with_basename<'a>(
&'a self,
_basename: &'a Id,
) -> Box<dyn Iterator<Item = EntityType> + 'a> {
Box::new(std::iter::empty())
}
}
#[derive(Debug, Clone)]
pub struct AllEntitiesNoAttrsSchema;
impl Schema for AllEntitiesNoAttrsSchema {
type EntityTypeDescription = NullEntityTypeDescription;
fn entity_type(&self, entity_type: &EntityType) -> Option<NullEntityTypeDescription> {
Some(NullEntityTypeDescription {
ty: entity_type.clone(),
})
}
fn action(&self, action: &EntityUID) -> Option<Arc<Entity>> {
Some(Arc::new(Entity::new(
action.clone(),
HashMap::new(),
HashSet::new(),
)))
}
fn entity_types_with_basename<'a>(
&'a self,
basename: &'a Id,
) -> Box<dyn Iterator<Item = EntityType> + 'a> {
Box::new(std::iter::once(EntityType::Concrete(
Name::unqualified_name(basename.clone()),
)))
}
}
pub trait EntityTypeDescription {
fn entity_type(&self) -> EntityType;
fn attr_type(&self, attr: &str) -> Option<SchemaType>;
fn required_attrs<'s>(&'s self) -> Box<dyn Iterator<Item = SmolStr> + 's>;
fn allowed_parent_types(&self) -> Arc<HashSet<EntityType>>;
}
#[derive(Debug, Clone)]
pub struct NullEntityTypeDescription {
ty: EntityType,
}
impl EntityTypeDescription for NullEntityTypeDescription {
fn entity_type(&self) -> EntityType {
self.ty.clone()
}
fn attr_type(&self, _attr: &str) -> Option<SchemaType> {
None
}
fn required_attrs(&self) -> Box<dyn Iterator<Item = SmolStr>> {
Box::new(std::iter::empty())
}
fn allowed_parent_types(&self) -> Arc<HashSet<EntityType>> {
Arc::new(HashSet::new())
}
}