#[derive(Debug, Clone)]
pub struct PatchGraph {
pub nodes: Vec<PatchNode>,
pub edges: Vec<PatchEdge>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum NodePurity {
Pure,
Stateful,
Unknown,
}
#[derive(Debug, Clone)]
pub struct PatchNode {
pub id: String,
pub object_name: String,
pub args: Vec<String>,
pub num_inlets: u32,
pub num_outlets: u32,
pub is_signal: bool,
pub varname: Option<String>,
pub hot_inlets: Vec<bool>,
pub purity: NodePurity,
pub attrs: Vec<(String, String)>,
pub code: Option<String>,
}
#[derive(Debug, Clone)]
pub struct PatchEdge {
pub source_id: String,
pub source_outlet: u32,
pub dest_id: String,
pub dest_inlet: u32,
pub is_feedback: bool,
pub order: Option<u32>,
}
impl PatchGraph {
pub fn new() -> Self {
PatchGraph {
nodes: Vec::new(),
edges: Vec::new(),
}
}
pub fn add_node(&mut self, node: PatchNode) -> &str {
self.nodes.push(node);
&self.nodes.last().unwrap().id
}
pub fn add_edge(&mut self, edge: PatchEdge) {
self.edges.push(edge);
}
pub fn find_node(&self, id: &str) -> Option<&PatchNode> {
self.nodes.iter().find(|n| n.id == id)
}
pub fn find_node_mut(&mut self, id: &str) -> Option<&mut PatchNode> {
self.nodes.iter_mut().find(|n| n.id == id)
}
}
impl Default for PatchGraph {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_node_purity_equality() {
assert_eq!(NodePurity::Pure, NodePurity::Pure);
assert_eq!(NodePurity::Stateful, NodePurity::Stateful);
assert_eq!(NodePurity::Unknown, NodePurity::Unknown);
assert_ne!(NodePurity::Pure, NodePurity::Stateful);
assert_ne!(NodePurity::Pure, NodePurity::Unknown);
}
#[test]
fn test_patch_edge_order_default() {
let edge = PatchEdge {
source_id: "a".into(),
source_outlet: 0,
dest_id: "b".into(),
dest_inlet: 0,
is_feedback: false,
order: None,
};
assert_eq!(edge.order, None);
}
#[test]
fn test_patch_edge_order_set() {
let edge = PatchEdge {
source_id: "a".into(),
source_outlet: 0,
dest_id: "b".into(),
dest_inlet: 0,
is_feedback: false,
order: Some(2),
};
assert_eq!(edge.order, Some(2));
}
#[test]
fn test_patch_node_hot_inlets() {
let node = PatchNode {
id: "test".into(),
object_name: "cycle~".into(),
args: vec![],
num_inlets: 2,
num_outlets: 1,
is_signal: true,
varname: None,
hot_inlets: vec![true, false],
purity: NodePurity::Pure,
attrs: vec![],
code: None,
};
assert!(node.hot_inlets[0]);
assert!(!node.hot_inlets[1]);
assert_eq!(node.purity, NodePurity::Pure);
}
}