use crate::{
prelude::{
Flowchart, FlowchartConfiguration, FlowchartConfigurationBuilder, FlowchartEdge,
FlowchartEdgeBuilder, FlowchartNode, FlowchartNodeBuilder,
},
shared::{StyleClass, StyleClassBuilder, generic_diagram::GenericDiagramBuilder},
traits::DiagramBuilder,
};
#[derive(Default, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct FlowchartBuilder {
generic: GenericDiagramBuilder<FlowchartNode, FlowchartEdge, FlowchartConfiguration>,
}
impl From<FlowchartBuilder> for Flowchart {
fn from(builder: FlowchartBuilder) -> Self {
let generic = builder.generic.into();
Flowchart { generic }
}
}
impl DiagramBuilder for FlowchartBuilder {
type Configuration = FlowchartConfiguration;
type ConfigurationBuilder = FlowchartConfigurationBuilder;
type Diagram = Flowchart;
type Edge = FlowchartEdge;
type EdgeBuilder = FlowchartEdgeBuilder;
type Node = FlowchartNode;
type NodeBuilder = FlowchartNodeBuilder;
type Error = crate::errors::Error;
fn configuration(
mut self,
configuration: Self::ConfigurationBuilder,
) -> Result<Self, Self::Error> {
self.generic = self.generic.configuration(configuration)?;
Ok(self)
}
fn edge(
&mut self,
mut edge: Self::EdgeBuilder,
) -> Result<alloc::rc::Rc<Self::Edge>, Self::Error> {
edge = edge.id(self.number_of_edges());
self.generic.edge(edge)
}
fn get_node_by_id(&self, id: u64) -> Option<alloc::rc::Rc<Self::Node>> {
self.generic.get_node_by_id(id)
}
fn node(&mut self, node: Self::NodeBuilder) -> Result<alloc::rc::Rc<Self::Node>, Self::Error> {
self.generic.node(node)
}
fn nodes(&self) -> impl Iterator<Item = &alloc::rc::Rc<Self::Node>> + '_ {
self.generic.nodes()
}
fn number_of_edges(&self) -> usize {
self.generic.number_of_edges()
}
fn number_of_nodes(&self) -> usize {
self.generic.number_of_nodes()
}
fn style_class(
&mut self,
style_class: StyleClassBuilder,
) -> Result<alloc::rc::Rc<StyleClass>, Self::Error> {
self.generic.style_class(style_class)
}
fn get_style_class_by_name(&self, name: &str) -> Option<alloc::rc::Rc<StyleClass>> {
self.generic.get_style_class_by_name(name)
}
}
#[cfg(test)]
mod tests {
use alloc::{boxed::Box, vec::Vec};
use super::*;
use crate::{
prelude::{FlowchartConfigurationBuilder, FlowchartEdgeBuilder, FlowchartNodeBuilder},
shared::{StyleClassBuilder, StyleProperty, style_class::Color},
traits::{
ConfigurationBuilder, DiagramBuilder, EdgeBuilder, NodeBuilder, edge::Edge, node::Node,
},
};
#[test]
fn test_flowchart_builder() -> Result<(), Box<dyn core::error::Error>> {
let mut builder = FlowchartBuilder::default();
let config = FlowchartConfigurationBuilder::default().title("My Flowchart")?;
builder = builder.configuration(config)?;
let style_class_builder = StyleClassBuilder::default()
.name("myStyle")?
.property(StyleProperty::Fill(Color::from((255, 0, 0))))?;
let style_class = builder.style_class(style_class_builder)?;
assert_eq!(style_class.name(), "myStyle");
assert!(builder.get_style_class_by_name("myStyle").is_some());
let node_builder = FlowchartNodeBuilder::default().label("Node A")?;
let node_a = builder.node(node_builder)?;
assert_eq!(builder.number_of_nodes(), 1);
assert!(builder.get_node_by_id(node_a.id()).is_some());
let node_builder_b = FlowchartNodeBuilder::default().label("Node B")?;
let node_b = builder.node(node_builder_b)?;
assert_eq!(builder.number_of_nodes(), 2);
let nodes: Vec<_> = builder.nodes().collect();
assert_eq!(nodes.len(), 2);
let edge_builder =
FlowchartEdgeBuilder::default().source(node_a.clone())?.destination(node_b.clone())?;
let edge = builder.edge(edge_builder)?;
assert_eq!(builder.number_of_edges(), 1);
assert_eq!(edge.source().id(), node_a.id());
assert_eq!(edge.destination().id(), node_b.id());
let _flowchart: Flowchart = builder.into();
Ok(())
}
}