use super::SchemaType;
use crate::ast::{Eid, Entity, EntityType, EntityUID};
use crate::entities::{Name, UnreservedId};
use nonempty::NonEmpty;
use smol_str::SmolStr;
use std::collections::HashSet;
use std::sync::Arc;
pub trait Schema {
type EntityTypeDescription: EntityTypeDescription;
type ActionEntityIterator: IntoIterator<Item = Arc<Entity>>;
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 UnreservedId,
) -> Box<dyn Iterator<Item = EntityType> + 'a>;
fn action_entities(&self) -> Self::ActionEntityIterator;
}
#[derive(Debug, Clone)]
pub struct NoEntitiesSchema;
impl Schema for NoEntitiesSchema {
type EntityTypeDescription = NullEntityTypeDescription;
type ActionEntityIterator = std::iter::Empty<Arc<Entity>>;
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 UnreservedId,
) -> Box<dyn Iterator<Item = EntityType> + 'a> {
Box::new(std::iter::empty())
}
fn action_entities(&self) -> std::iter::Empty<Arc<Entity>> {
std::iter::empty()
}
}
#[derive(Debug, Clone)]
pub struct AllEntitiesNoAttrsSchema;
impl Schema for AllEntitiesNoAttrsSchema {
type EntityTypeDescription = NullEntityTypeDescription;
type ActionEntityIterator = std::iter::Empty<Arc<Entity>>;
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_with_attr_partial_value(
action.clone(),
[],
HashSet::new(),
HashSet::new(),
[],
)))
}
fn entity_types_with_basename<'a>(
&'a self,
basename: &'a UnreservedId,
) -> Box<dyn Iterator<Item = EntityType> + 'a> {
Box::new(std::iter::once(EntityType::from(Name::unqualified_name(
basename.clone(),
))))
}
fn action_entities(&self) -> std::iter::Empty<Arc<Entity>> {
std::iter::empty()
}
}
pub trait EntityTypeDescription {
fn entity_type(&self) -> EntityType;
fn attr_type(&self, attr: &str) -> Option<SchemaType>;
fn tag_type(&self) -> Option<SchemaType>;
fn required_attrs<'s>(&'s self) -> Box<dyn Iterator<Item = SmolStr> + 's>;
fn allowed_parent_types(&self) -> Arc<HashSet<EntityType>>;
fn open_attributes(&self) -> bool;
fn enum_entity_eids(&self) -> Option<NonEmpty<Eid>>;
}
#[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 tag_type(&self) -> 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())
}
fn open_attributes(&self) -> bool {
false
}
fn enum_entity_eids(&self) -> Option<NonEmpty<Eid>> {
None
}
}
impl NullEntityTypeDescription {
pub fn new(ty: EntityType) -> Self {
Self { ty }
}
}