vis/src/lib.rs
2025-01-25 13:35:08 +01:00

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,
}