use facet::Facet;
use indexmap::IndexMap;
#[cfg(feature = "json-import")]
use crate::{
diagnostic::{ImportError, JsonDocumentKind},
source::{PackageRoot, SourceFile},
};
type FieldMap = IndexMap<String, NodeFieldInfo, std::hash::RandomState>;
#[derive(Debug, Clone, Facet, PartialEq, Eq)]
pub struct NodeTypesJson {
pub raw: String,
pub node_types: Vec<NodeInfo>,
}
impl NodeTypesJson {
#[cfg(feature = "json-import")]
pub fn from_source_file(
root: &PackageRoot,
source_file: SourceFile<String>,
) -> Result<SourceFile<Self>, ImportError> {
let path = root.join(&source_file.path);
let source_id = source_file.id;
let package_path = source_file.path.clone();
let node_types =
facet_json::from_str(&source_file.body).map_err(|source| ImportError::Json {
package_root: Some(root.as_path().to_owned()),
path: Some(path),
source_id: Some(source_id),
package_path: Some(package_path),
document: JsonDocumentKind::NodeTypes,
phase: "decode raw node-types.json",
source,
})?;
Ok(source_file.map(|raw| Self { raw, node_types }))
}
}
#[derive(Debug, Clone, Facet, PartialEq, Eq)]
pub struct NodeInfo {
#[facet(rename = "type")]
pub kind: String,
pub named: bool,
#[facet(default)]
pub root: bool,
#[facet(default)]
pub extra: bool,
#[facet(default)]
pub fields: NodeFieldTable,
pub children: Option<NodeFieldInfo>,
#[facet(default)]
pub subtypes: Vec<NodeTypeRef>,
}
#[derive(Debug, Clone, Default, Facet, PartialEq, Eq)]
#[facet(transparent)]
pub struct NodeFieldTable(FieldMap);
impl NodeFieldTable {
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn get(&self, name: &str) -> Option<&NodeFieldInfo> {
self.0.get(name)
}
pub fn iter(&self) -> impl Iterator<Item = (&str, &NodeFieldInfo)> {
self.0.iter().map(|(name, info)| (name.as_str(), info))
}
}
#[derive(Debug, Clone, Facet, PartialEq, Eq)]
pub struct NodeFieldInfo {
pub multiple: bool,
pub required: bool,
#[facet(default)]
pub types: Vec<NodeTypeRef>,
}
#[derive(Debug, Clone, Facet, PartialEq, Eq)]
pub struct NodeTypeRef {
#[facet(rename = "type")]
pub kind: String,
pub named: bool,
}