use std::collections::HashMap;
use std::default::Default;
use std::mem;
use crate::attributes::LABEL;
use crate::graph::*;
#[derive(Debug)]
pub struct RootBuilder {
graph: Graph,
current: SubgraphInfo,
defaults: Defaults,
}
impl RootBuilder {
#[must_use]
pub fn build(mut self) -> Graph {
self.graph.subgraphs.insert(ROOT, self.current);
self.graph
}
}
#[derive(Debug)]
pub struct SubgraphBuilder<'a> {
graph: &'a mut Graph,
entity: Entity,
current: SubgraphInfo,
defaults: Defaults,
}
impl SubgraphBuilder<'_> {
pub fn build(self) -> Entity {
self.entity
}
}
impl Drop for SubgraphBuilder<'_> {
fn drop(&mut self) {
self.graph
.subgraphs
.insert(self.entity, mem::take(&mut self.current));
}
}
pub trait Builder {
fn new_node(&mut self, label: impl Into<String>) -> Entity;
fn new_edge(&mut self, head: Entity, tail: Entity) -> Entity;
fn new_subgraph(&mut self) -> SubgraphBuilder;
fn new_cluster(&mut self, label: impl Into<String>) -> SubgraphBuilder;
fn new_node_with(&mut self, label: impl Into<String>, attribs: Attributes) -> Entity {
let entity = self.new_node(label);
self.attributes_mut(entity).extend(attribs);
entity
}
fn new_edge_with(&mut self, head: Entity, tail: Entity, attribs: Attributes) -> Entity {
let entity = self.new_edge(head, tail);
self.attributes_mut(entity).extend(attribs);
entity
}
fn new_subgraph_with(&mut self, attribs: Attributes) -> SubgraphBuilder {
let mut result = self.new_subgraph();
result.attributes_mut(result.entity).extend(attribs);
result
}
fn new_cluster_with(
&mut self,
label: impl Into<String>,
attribs: Attributes,
) -> SubgraphBuilder {
let mut result = self.new_cluster(label);
result.attributes_mut(result.entity).extend(attribs);
result
}
fn defaults(&self, kind: Kind) -> Option<&Attributes>;
fn defaults_mut(&mut self, kind: Kind) -> &mut Attributes;
fn attributes(&self, entity: Entity) -> &Attributes;
fn attributes_mut(&mut self, entity: Entity) -> &mut Attributes;
}
impl RootBuilder {
pub(crate) fn new() -> RootBuilder {
RootBuilder {
graph: Graph {
attributes: HashMap::from([(ROOT, HashMap::new())]),
subgraphs: HashMap::new(),
edges: HashMap::new(),
latest: 0,
},
current: SubgraphInfo::default(),
defaults: HashMap::new(),
}
}
fn new_builder(&mut self, entity: Entity) -> SubgraphBuilder {
SubgraphBuilder {
graph: &mut self.graph,
entity,
current: SubgraphInfo::default(),
defaults: self.defaults.clone(),
}
}
}
impl SubgraphBuilder<'_> {
fn new_builder(&mut self, entity: Entity) -> SubgraphBuilder {
SubgraphBuilder {
graph: self.graph,
entity,
current: SubgraphInfo::default(),
defaults: self.defaults.clone(),
}
}
}
impl Builder for RootBuilder {
fn new_node(&mut self, label: impl Into<String>) -> Entity {
let entity = self.graph.new_node(label, &self.defaults);
self.current.nodes.push(entity);
entity
}
fn new_edge(&mut self, head: Entity, tail: Entity) -> Entity {
let entity = self.graph.new_edge(head, tail, &self.defaults);
self.current.edges.push(entity);
entity
}
fn new_subgraph(&mut self) -> SubgraphBuilder {
let entity = self.graph.register(Kind::Subgraph, &self.defaults);
self.current.subgraphs.push(entity);
self.new_builder(entity)
}
fn new_cluster(&mut self, label: impl Into<String>) -> SubgraphBuilder {
let entity = self.graph.register(Kind::Cluster, &self.defaults);
self.current.subgraphs.push(entity);
self.attributes_mut(entity).insert(LABEL, label.into());
self.new_builder(entity)
}
fn defaults(&self, kind: Kind) -> Option<&Attributes> {
self.defaults.get(&kind)
}
fn defaults_mut(&mut self, kind: Kind) -> &mut Attributes {
self.defaults.entry(kind).or_default()
}
fn attributes(&self, entity: Entity) -> &Attributes {
self.graph.attributes(entity)
}
fn attributes_mut(&mut self, entity: Entity) -> &mut Attributes {
self.graph.attributes_mut(entity)
}
}
impl Builder for SubgraphBuilder<'_> {
fn new_node(&mut self, label: impl Into<String>) -> Entity {
let entity = self.graph.new_node(label, &self.defaults);
self.current.nodes.push(entity);
entity
}
fn new_edge(&mut self, head: Entity, tail: Entity) -> Entity {
let entity = self.graph.new_edge(head, tail, &self.defaults);
self.current.edges.push(entity);
entity
}
fn new_subgraph(&mut self) -> SubgraphBuilder {
let entity = self.graph.register(Kind::Subgraph, &self.defaults);
self.current.subgraphs.push(entity);
self.new_builder(entity)
}
fn new_cluster(&mut self, label: impl Into<String>) -> SubgraphBuilder {
let entity = self.graph.register(Kind::Cluster, &self.defaults);
self.current.subgraphs.push(entity);
self.attributes_mut(entity).insert(LABEL, label.into());
self.new_builder(entity)
}
fn defaults(&self, kind: Kind) -> Option<&Attributes> {
self.defaults.get(&kind)
}
fn defaults_mut(&mut self, kind: Kind) -> &mut Attributes {
self.defaults.entry(kind).or_default()
}
fn attributes(&self, entity: Entity) -> &Attributes {
self.graph.attributes(entity)
}
fn attributes_mut(&mut self, entity: Entity) -> &mut Attributes {
self.graph.attributes_mut(entity)
}
}