139 lines
3.5 KiB
Rust
139 lines
3.5 KiB
Rust
pub mod parse;
|
|
pub mod render;
|
|
|
|
use crate::parse::tokens::TokenType;
|
|
use std::collections::HashMap;
|
|
use std::fmt::Display;
|
|
|
|
pub struct Vis {
|
|
pub structure: VisNode,
|
|
pub styles: Vec<StyleNode>,
|
|
}
|
|
|
|
impl Vis {
|
|
pub fn get_node(&self, id: &str) -> Option<&VisNode> {
|
|
if self.structure.id == id {
|
|
return Some(&self.structure);
|
|
} else {
|
|
for child in &self.structure.children {
|
|
if child.id == id {
|
|
return Some(child);
|
|
}
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
pub fn get_style(&self, node: &VisNode) -> Option<&StyleNode> {
|
|
let style = self.styles.iter().find(|s| s.id_ref == node.id);
|
|
if style.is_none() && node.id != "structure" {
|
|
for child in &node.children {
|
|
if let Some(style) = self.get_style(child) {
|
|
return Some(style);
|
|
}
|
|
}
|
|
None
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub enum NodeType {
|
|
Node,
|
|
Edge,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct VisNode {
|
|
pub node_type: NodeType,
|
|
pub id: String,
|
|
targetid: Option<String>,
|
|
pub label: Option<String>,
|
|
pub children: Vec<VisNode>,
|
|
pub parent: Option<String>,
|
|
edgetype: Option<TokenType>,
|
|
}
|
|
|
|
impl VisNode {
|
|
pub fn new_node(
|
|
id: impl Into<String>,
|
|
label: Option<impl Into<String>>,
|
|
children: Vec<VisNode>,
|
|
) -> Self {
|
|
Self {
|
|
id: id.into(),
|
|
targetid: None,
|
|
label: label.map(|s| s.into()),
|
|
children,
|
|
parent: None,
|
|
node_type: NodeType::Node,
|
|
edgetype: None,
|
|
}
|
|
}
|
|
|
|
pub fn new_edge(
|
|
sourceid: impl Into<String>,
|
|
targetid: impl Into<String>,
|
|
edgetype: TokenType,
|
|
label: Option<impl Into<String>>,
|
|
) -> Self {
|
|
Self {
|
|
id: sourceid.into(),
|
|
targetid: Some(targetid.into()),
|
|
edgetype: Some(edgetype),
|
|
label: label.map(|l| l.into()),
|
|
children: vec![],
|
|
parent: None,
|
|
node_type: NodeType::Edge,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Display for VisNode {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match &self.node_type {
|
|
NodeType::Node => {
|
|
let mut string = String::new();
|
|
string.push_str(&format!(
|
|
"Node {{{}: {}",
|
|
self.id,
|
|
self.label.as_ref().unwrap_or(&"".to_string())
|
|
));
|
|
for child in &self.children {
|
|
string.push_str(&format!(" {}", child));
|
|
}
|
|
string.push('}');
|
|
write!(f, "{}", string)
|
|
}
|
|
NodeType::Edge => {
|
|
write!(f, "Edge {{")?;
|
|
write!(
|
|
f,
|
|
"{} {} {:?}",
|
|
self.id,
|
|
self.targetid.as_ref().unwrap(),
|
|
self.edgetype
|
|
)?;
|
|
if let Some(label) = &self.label {
|
|
write!(f, " {}", label)?;
|
|
}
|
|
write!(f, "}}")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct StyleNode {
|
|
pub id_ref: String,
|
|
pub containertype: ContainerType,
|
|
pub attributes: HashMap<String, String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum ContainerType {
|
|
NonGroup, // needs thinking about
|
|
Group,
|
|
}
|