use crate::output::comment;
use crate::output::diagnostic;
use crate::output::path;
use crate::output::primitive_data;
use crate::output::type_system::data;
use std::collections::VecDeque;
use std::sync::Arc;
#[derive(Clone, Debug, PartialEq)]
pub struct Node {
pub class: Class,
pub brief: Option<comment::Brief>,
pub summary: Option<comment::Comment>,
pub node_type: NodeType,
pub data_type: Option<data::Type>,
pub data: Vec<NodeData>,
}
impl From<NodeType> for Node {
fn from(node_type: NodeType) -> Self {
Node {
class: Class::Misc,
brief: None,
summary: None,
node_type,
data_type: None,
data: vec![],
}
}
}
impl Node {
pub fn iter_flattened_nodes(&self) -> FlattenedNodeIter {
FlattenedNodeIter {
remaining: VecDeque::from(vec![self]),
}
}
pub fn iter_flattened_node_data(&self) -> FlattenedNodeDataIter {
FlattenedNodeDataIter {
remaining: self.data.iter().rev().collect(),
}
}
pub fn iter_diagnostics(&self) -> impl Iterator<Item = &diagnostic::Diagnostic> + '_ {
self.iter_flattened_node_data().filter_map(|x| match x {
NodeData::Diagnostic(d) => Some(d),
_ => None,
})
}
pub fn get_diagnostic(&self) -> Option<&diagnostic::Diagnostic> {
let mut result: Option<&diagnostic::Diagnostic> = None;
for diag in self.iter_diagnostics() {
if diag.adjusted_level == diagnostic::Level::Error {
return Some(diag);
}
if let Some(cur) = result.as_mut() {
if diag.adjusted_level > cur.adjusted_level {
*cur = diag;
}
} else {
result = Some(diag);
}
}
result
}
pub fn data_type(&self) -> data::Type {
self.data_type.clone().unwrap_or_default()
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum NodeType {
ProtoMessage(&'static str),
ProtoPrimitive(&'static str, primitive_data::PrimitiveData),
ProtoMissingOneOf,
NodeReference(u64, NodeReference),
YamlMap,
YamlArray,
YamlPrimitive(primitive_data::PrimitiveData),
ResolvedUri(String),
AstNode,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Class {
Misc,
Type,
Expression,
Relation,
}
#[derive(Clone, Debug, PartialEq)]
pub enum NodeData {
Child(Child),
Diagnostic(diagnostic::Diagnostic),
DataType(data::Type),
Comment(comment::Comment),
}
#[derive(Clone, Debug, PartialEq)]
pub struct Child {
pub path_element: path::PathElement,
pub node: Arc<Node>,
pub recognized: bool,
}
#[derive(Clone, Debug, PartialEq)]
pub struct NodeReference {
pub path: path::PathBuf,
pub node: Arc<Node>,
}
pub struct FlattenedNodeIter<'a> {
remaining: VecDeque<&'a Node>,
}
impl<'a> Iterator for FlattenedNodeIter<'a> {
type Item = &'a Node;
fn next(&mut self) -> Option<Self::Item> {
let maybe_node = self.remaining.pop_back();
if let Some(node) = maybe_node {
self.remaining
.extend(node.data.iter().rev().filter_map(|x| -> Option<&Node> {
if let NodeData::Child(child) = x {
Some(&child.node)
} else {
None
}
}));
}
maybe_node
}
}
pub struct FlattenedNodeDataIter<'a> {
remaining: VecDeque<&'a NodeData>,
}
impl<'a> Iterator for FlattenedNodeDataIter<'a> {
type Item = &'a NodeData;
fn next(&mut self) -> Option<Self::Item> {
let maybe_node_data = self.remaining.pop_back();
if let Some(NodeData::Child(child)) = maybe_node_data {
self.remaining.extend(child.node.data.iter().rev())
}
maybe_node_data
}
}