use std::collections::BTreeMap;
use facet::{Facet, Shape};
use phon::derive::{DeriveError, of_shape};
use phon_schema::{Schema, SchemaId};
#[derive(Clone, Debug)]
pub struct Root {
pub name: String,
pub id: SchemaId,
}
#[derive(Clone, Debug, Default)]
pub struct Module {
pub schemas: Vec<Schema>,
pub roots: Vec<Root>,
}
impl Module {
pub fn from_shapes(roots: &[&'static Shape]) -> Result<Module, DeriveError> {
let mut by_id: BTreeMap<u64, Schema> = BTreeMap::new();
let mut root_list = Vec::with_capacity(roots.len());
for &shape in roots {
let derived = of_shape(shape)?;
for s in derived.schemas {
by_id.entry(s.id.as_u64()).or_insert(s);
}
root_list.push(Root {
name: shape.type_identifier.to_string(),
id: derived.root,
});
}
Ok(Module {
schemas: by_id.into_values().collect(),
roots: root_list,
})
}
#[must_use]
pub fn schema(&self, id: SchemaId) -> Option<&Schema> {
self.schemas.iter().find(|s| s.id == id)
}
}
#[derive(Default)]
pub struct Builder {
shapes: Vec<&'static Shape>,
}
impl Builder {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn add<'a, T: Facet<'a>>(mut self) -> Self {
self.shapes.push(T::SHAPE);
self
}
pub fn build(&self) -> Result<Module, DeriveError> {
Module::from_shapes(&self.shapes)
}
}