use std::ops::Deref;
use crate::core::ids::{
BindingId, EdgeId, GraphId, GroupId, NodeId, PortId, StickyNoteId, SymbolId,
};
use crate::core::imports::GraphImport;
use crate::core::validate::{GraphValidationError, validate_graph};
use super::binding::Binding;
use super::edge::Edge;
use super::graph::Graph;
use super::node::Node;
use super::port::Port;
use super::resources::{Group, StickyNote, Symbol};
#[derive(Debug, Clone, Default)]
pub struct GraphBuilder {
graph: Graph,
}
impl GraphBuilder {
pub fn new(graph_id: GraphId) -> Self {
Self {
graph: Graph::new(graph_id),
}
}
pub(crate) fn from_graph(graph: Graph) -> Self {
Self { graph }
}
pub fn graph_id(&self) -> GraphId {
self.graph.graph_id()
}
pub fn graph(&self) -> &Graph {
&self.graph
}
pub fn with_import(mut self, id: GraphId, import: GraphImport) -> Self {
self.insert_import(id, import);
self
}
pub fn with_symbol(mut self, id: SymbolId, symbol: Symbol) -> Self {
self.insert_symbol(id, symbol);
self
}
pub fn with_node(mut self, id: NodeId, node: Node) -> Self {
self.insert_node(id, node);
self
}
pub fn with_port(mut self, id: PortId, port: Port) -> Self {
self.insert_port(id, port);
self
}
pub fn with_edge(mut self, id: EdgeId, edge: Edge) -> Self {
self.insert_edge(id, edge);
self
}
pub fn with_group(mut self, id: GroupId, group: Group) -> Self {
self.insert_group(id, group);
self
}
pub fn with_sticky_note(mut self, id: StickyNoteId, note: StickyNote) -> Self {
self.insert_sticky_note(id, note);
self
}
pub fn with_binding(mut self, id: BindingId, binding: Binding) -> Self {
self.insert_binding(id, binding);
self
}
pub fn insert_import(&mut self, id: GraphId, import: GraphImport) -> Option<GraphImport> {
self.graph.insert_import(id, import)
}
pub fn update_import<R>(
&mut self,
id: &GraphId,
f: impl FnOnce(&mut GraphImport) -> R,
) -> Option<R> {
self.graph.update_import(id, f)
}
pub fn remove_import(&mut self, id: &GraphId) -> Option<GraphImport> {
self.graph.remove_import(id)
}
pub fn clear_imports(&mut self) {
self.graph.clear_imports();
}
pub fn retain_imports(&mut self, f: impl FnMut(&GraphId, &mut GraphImport) -> bool) {
self.graph.retain_imports(f);
}
pub fn insert_symbol(&mut self, id: SymbolId, symbol: Symbol) -> Option<Symbol> {
self.graph.insert_symbol(id, symbol)
}
pub fn update_symbol<R>(
&mut self,
id: &SymbolId,
f: impl FnOnce(&mut Symbol) -> R,
) -> Option<R> {
self.graph.update_symbol(id, f)
}
pub fn remove_symbol(&mut self, id: &SymbolId) -> Option<Symbol> {
self.graph.remove_symbol(id)
}
pub fn clear_symbols(&mut self) {
self.graph.clear_symbols();
}
pub fn retain_symbols(&mut self, f: impl FnMut(&SymbolId, &mut Symbol) -> bool) {
self.graph.retain_symbols(f);
}
pub fn insert_node(&mut self, id: NodeId, node: Node) -> Option<Node> {
self.graph.insert_node(id, node)
}
pub fn update_node<R>(&mut self, id: &NodeId, f: impl FnOnce(&mut Node) -> R) -> Option<R> {
self.graph.update_node(id, f)
}
pub fn remove_node(&mut self, id: &NodeId) -> Option<Node> {
self.graph.remove_node(id)
}
pub fn clear_nodes(&mut self) {
self.graph.clear_nodes();
}
pub fn retain_nodes(&mut self, f: impl FnMut(&NodeId, &mut Node) -> bool) {
self.graph.retain_nodes(f);
}
pub fn insert_port(&mut self, id: PortId, port: Port) -> Option<Port> {
self.graph.insert_port(id, port)
}
pub fn update_port<R>(&mut self, id: &PortId, f: impl FnOnce(&mut Port) -> R) -> Option<R> {
self.graph.update_port(id, f)
}
pub fn remove_port(&mut self, id: &PortId) -> Option<Port> {
self.graph.remove_port(id)
}
pub fn clear_ports(&mut self) {
self.graph.clear_ports();
}
pub fn retain_ports(&mut self, f: impl FnMut(&PortId, &mut Port) -> bool) {
self.graph.retain_ports(f);
}
pub fn insert_edge(&mut self, id: EdgeId, edge: Edge) -> Option<Edge> {
self.graph.insert_edge(id, edge)
}
pub fn update_edge<R>(&mut self, id: &EdgeId, f: impl FnOnce(&mut Edge) -> R) -> Option<R> {
self.graph.update_edge(id, f)
}
pub fn remove_edge(&mut self, id: &EdgeId) -> Option<Edge> {
self.graph.remove_edge(id)
}
pub fn clear_edges(&mut self) {
self.graph.clear_edges();
}
pub fn retain_edges(&mut self, f: impl FnMut(&EdgeId, &mut Edge) -> bool) {
self.graph.retain_edges(f);
}
pub fn insert_group(&mut self, id: GroupId, group: Group) -> Option<Group> {
self.graph.insert_group(id, group)
}
pub fn update_group<R>(&mut self, id: &GroupId, f: impl FnOnce(&mut Group) -> R) -> Option<R> {
self.graph.update_group(id, f)
}
pub fn remove_group(&mut self, id: &GroupId) -> Option<Group> {
self.graph.remove_group(id)
}
pub fn clear_groups(&mut self) {
self.graph.clear_groups();
}
pub fn retain_groups(&mut self, f: impl FnMut(&GroupId, &mut Group) -> bool) {
self.graph.retain_groups(f);
}
pub fn insert_sticky_note(&mut self, id: StickyNoteId, note: StickyNote) -> Option<StickyNote> {
self.graph.insert_sticky_note(id, note)
}
pub fn update_sticky_note<R>(
&mut self,
id: &StickyNoteId,
f: impl FnOnce(&mut StickyNote) -> R,
) -> Option<R> {
self.graph.update_sticky_note(id, f)
}
pub fn remove_sticky_note(&mut self, id: &StickyNoteId) -> Option<StickyNote> {
self.graph.remove_sticky_note(id)
}
pub fn clear_sticky_notes(&mut self) {
self.graph.clear_sticky_notes();
}
pub fn retain_sticky_notes(&mut self, f: impl FnMut(&StickyNoteId, &mut StickyNote) -> bool) {
self.graph.retain_sticky_notes(f);
}
pub fn insert_binding(&mut self, id: BindingId, binding: Binding) -> Option<Binding> {
self.graph.insert_binding(id, binding)
}
pub fn update_binding<R>(
&mut self,
id: &BindingId,
f: impl FnOnce(&mut Binding) -> R,
) -> Option<R> {
self.graph.update_binding(id, f)
}
pub fn remove_binding(&mut self, id: &BindingId) -> Option<Binding> {
self.graph.remove_binding(id)
}
pub fn clear_bindings(&mut self) {
self.graph.clear_bindings();
}
pub fn retain_bindings(&mut self, f: impl FnMut(&BindingId, &mut Binding) -> bool) {
self.graph.retain_bindings(f);
}
pub fn build(self) -> Result<Graph, Vec<GraphValidationError>> {
let report = validate_graph(&self.graph);
if report.is_ok() {
Ok(self.graph)
} else {
Err(report.into_errors())
}
}
pub fn build_unchecked(self) -> Graph {
self.graph
}
}
impl Deref for GraphBuilder {
type Target = Graph;
fn deref(&self) -> &Self::Target {
&self.graph
}
}
impl AsRef<Graph> for GraphBuilder {
fn as_ref(&self) -> &Graph {
&self.graph
}
}
impl From<GraphBuilder> for Graph {
fn from(builder: GraphBuilder) -> Self {
builder.build_unchecked()
}
}