use super::{Form, Kind};
use crate::parse::ParseOptions;
use crate::processor::Processor;
use crate::resolve::CORE_TEXT;
use crate::tree::Node;
use crate::validate::universal::Universal;
use serde::Serialize;
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Known {
pub name: String,
pub tokens: Vec<String>,
pub forms: Vec<Form>,
pub examples: Vec<&'static str>,
pub up_to: usize,
pub flag: bool,
pub quoted: bool,
pub breakpoints: bool,
}
impl Known {
fn new(name: &str, kind: &Kind, breakpoints: bool) -> Self {
Self {
name: name.to_string(),
tokens: kind.tokens.iter().map(ToString::to_string).collect(),
forms: kind.forms.to_vec(),
examples: kind.examples.to_vec(),
up_to: kind.up_to,
flag: kind.flag,
quoted: kind.quoted,
breakpoints,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
pub struct Vocabulary {
pub common: Vec<Known>,
pub attributes: Vec<Known>,
pub layout: Vec<Known>,
}
#[must_use]
pub fn vocabulary() -> Vocabulary {
let (common, attributes) = Universal::ALL
.iter()
.map(|param| {
(
param.is_common(),
Known::new(param.name(), ¶m.kind(), param.takes_breakpoint()),
)
})
.partition::<Vec<_>, _>(|(common, _)| *common);
let core = Processor::new("core.comp.md", CORE_TEXT).parse(&ParseOptions::default());
let layout = core
.tree()
.children
.iter()
.find_map(|node| match node {
Node::ComponentSignature(fence) if fence.name == "box" => fence.signature.as_ref(),
_ => None,
})
.map(|signature| {
signature
.params
.iter()
.map(|declared| {
Known::new(&declared.name, &Kind::declared(&declared.declared), true)
})
.collect()
})
.unwrap_or_default();
Vocabulary {
common: common.into_iter().map(|(_, known)| known).collect(),
attributes: attributes.into_iter().map(|(_, known)| known).collect(),
layout,
}
}