summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorseancarroll <seanc28@gmail.com>2021-03-23 23:22:09 -0500
committerseancarroll <seanc28@gmail.com>2021-03-23 23:22:09 -0500
commit889162257cda19bafd4ff344cb878565f2562794 (patch)
tree4a322537d9092637b8eeb510122db02a2936f148 /src
parent2f7ecf77781f181b8de178e0ec2f4a37a958a412 (diff)
downloaddotavious-889162257cda19bafd4ff344cb878565f2562794.zip
support Into<String> in more scenarios to remove the need for users to always have to perform a .to_string
Diffstat (limited to 'src')
-rw-r--r--src/attributes/mod.rs6
-rw-r--r--src/dot.rs103
-rw-r--r--src/lib.rs50
3 files changed, 87 insertions, 72 deletions
diff --git a/src/attributes/mod.rs b/src/attributes/mod.rs
index 0cdfa99..94ade1b 100644
--- a/src/attributes/mod.rs
+++ b/src/attributes/mod.rs
@@ -495,7 +495,7 @@ pub trait GraphAttributes<'a> {
}
/// An escString or an HTML label.
- fn label(&mut self, label: String) -> &mut Self {
+ fn label<S: Into<String>>(&mut self, label: S) -> &mut Self {
Attributes::label(self.get_attributes_mut(), label);
self
}
@@ -1047,8 +1047,8 @@ impl Attributes {
)
}
- pub fn label(attributes: &mut IndexMap<String, AttributeText>, text: String) {
- Self::add_attribute(attributes, "label", AttributeText::quoted(text));
+ pub fn label<S: Into<String>>(attributes: &mut IndexMap<String, AttributeText>, text: S) {
+ Self::add_attribute(attributes, "label", AttributeText::quoted(text.into()));
}
pub fn label_location(
diff --git a/src/dot.rs b/src/dot.rs
index a6828b7..f154dc9 100644
--- a/src/dot.rs
+++ b/src/dot.rs
@@ -316,26 +316,26 @@ pub struct GraphBuilder<'a> {
// TODO: id should be an escString
impl<'a> GraphBuilder<'a> {
- pub fn new_directed(id: Option<String>) -> Self {
- Self {
- id,
- is_directed: true,
- strict: false,
- graph_attributes: IndexMap::new(),
- node_attributes: IndexMap::new(),
- edge_attributes: IndexMap::new(),
- sub_graphs: Vec::new(),
- nodes: Vec::new(),
- edges: Vec::new(),
- comment: None,
- errors: Vec::new(),
- }
+ pub fn new_directed() -> Self {
+ Self::new(None, true)
+ }
+
+ pub fn new_named_directed<S: Into<String>>(id: S) -> Self {
+ Self::new(Some(id.into()), true)
+ }
+
+ pub fn new_undirected() -> Self {
+ Self::new(None, false)
+ }
+
+ pub fn new_named_undirected<S: Into<String>>(id: S) -> Self {
+ Self::new(Some(id.into()), false)
}
- pub fn new_undirected(id: Option<String>) -> Self {
+ fn new(id: Option<String>, is_directed: bool) -> Self {
Self {
id,
- is_directed: false,
+ is_directed,
strict: false,
graph_attributes: IndexMap::new(),
node_attributes: IndexMap::new(),
@@ -377,16 +377,16 @@ impl<'a> GraphBuilder<'a> {
self
}
- pub fn add_attribute(
+ pub fn add_attribute<S: Into<String>>(
&mut self,
attribute_type: AttributeType,
- key: String,
+ key: S,
value: AttributeText<'a>,
) -> &mut Self {
match attribute_type {
- AttributeType::Graph => self.graph_attributes.insert(key, value),
- AttributeType::Edge => self.edge_attributes.insert(key, value),
- AttributeType::Node => self.node_attributes.insert(key, value),
+ AttributeType::Graph => self.graph_attributes.insert(key.into(), value),
+ AttributeType::Edge => self.edge_attributes.insert(key.into(), value),
+ AttributeType::Node => self.node_attributes.insert(key.into(), value),
};
self
}
@@ -503,9 +503,16 @@ pub struct SubGraphBuilder<'a> {
errors: Vec<ValidationError>,
}
-// TODO: id should be an escString
impl<'a> SubGraphBuilder<'a> {
- pub fn new(id: Option<String>) -> Self {
+ pub fn new() -> Self {
+ Self::new_inner(None)
+ }
+
+ pub fn new_named<S: Into<String>>(id: S) -> Self {
+ Self::new_inner(Some(id.into()))
+ }
+
+ fn new_inner(id: Option<String>) -> Self {
Self {
id,
graph_attributes: IndexMap::new(),
@@ -620,10 +627,10 @@ pub struct Node<'a> {
}
impl<'a> Node<'a> {
- pub fn new(id: String) -> Node<'a> {
+ pub fn new<S: Into<String>>(id: S) -> Node<'a> {
// TODO: constrain id
Node {
- id,
+ id: id.into(),
attributes: IndexMap::new(),
}
}
@@ -676,9 +683,9 @@ impl<'a> NodeAttributes<'a> for NodeBuilder<'a> {
}
impl<'a> NodeBuilder<'a> {
- pub fn new(id: String) -> Self {
+ pub fn new<S: Into<String>>(id: S) -> Self {
Self {
- id,
+ id: id.into(),
attributes: IndexMap::new(),
errors: Vec::new(),
}
@@ -710,26 +717,34 @@ pub struct Edge<'a> {
}
impl<'a> Edge<'a> {
- pub fn new(source: String, target: String) -> Self {
+ pub fn new<S, T>(source: S, target: T) -> Self
+ where
+ S: Into<String>,
+ T: Into<String>
+ {
Self {
- source,
+ source: source.into(),
source_port_position: None,
- target,
+ target: target.into(),
target_port_position: None,
attributes: IndexMap::new(),
}
}
- pub fn new_with_position(
- source: String,
+ pub fn new_with_position<S, T>(
+ source: S,
source_port_position: PortPosition,
- target: String,
+ target: T,
target_port_position: PortPosition,
- ) -> Self {
+ ) -> Self
+ where
+ S: Into<String>,
+ T: Into<String>
+ {
Self {
- source,
+ source: source.into(),
source_port_position: Some(source_port_position),
- target,
+ target: target.into(),
target_port_position: Some(target_port_position),
attributes: IndexMap::new(),
}
@@ -768,10 +783,10 @@ impl<'a> EdgeAttributes<'a> for EdgeBuilder<'a> {
}
impl<'a> EdgeBuilder<'a> {
- pub fn new(source: String, target: String) -> Self {
+ pub fn new<S: Into<String>, T: Into<String>>(source: S, target: T) -> Self {
Self {
- source,
- target,
+ source: source.into(),
+ target: target.into(),
source_port_position: None,
target_port_position: None,
attributes: IndexMap::new(),
@@ -779,15 +794,15 @@ impl<'a> EdgeBuilder<'a> {
}
}
- pub fn new_with_port_position(
- source: String,
+ pub fn new_with_port_position<S: Into<String>, T: Into<String>>(
+ source: S,
source_port_position: PortPosition,
- target: String,
+ target: T,
target_port_position: PortPosition,
) -> Self {
Self {
- source,
- target,
+ source: source.into(),
+ target: target.into(),
source_port_position: Some(source_port_position),
target_port_position: Some(target_port_position),
attributes: IndexMap::new(),
diff --git a/src/lib.rs b/src/lib.rs
index 3c4b2b1..b39ed4b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,7 +2,7 @@
#![cfg_attr(docsrs, deny(broken_intra_doc_links))]
//! Dotavious provides bindings to generate [DOT](https://graphviz.org/doc/info/lang.html)
-//! code used by the Graphviz (http://graphviz.org/) for visualising graphs.
+//! code used by the [Graphviz](http://graphviz.org/) for visualising graphs.
//! It also provides strongly typed attribute functions and offers almost complete
//! coverage of all Graphviz attributes and syntax.
//!
@@ -14,10 +14,10 @@
//! ```rust
//! use dotavious::{Dot, Edge, Graph, GraphBuilder, Node};
//!
-//! let g = GraphBuilder::new_directed(Some("example".to_string()))
-//! .add_node(Node::new("N0".to_string()))
-//! .add_node(Node::new("N1".to_string()))
-//! .add_edge(Edge::new("N0".to_string(), "N1".to_string()))
+//! let g = GraphBuilder::new_named_directed("example")
+//! .add_node(Node::new("N0"))
+//! .add_node(Node::new("N1"))
+//! .add_edge(Edge::new("N0", "N1"))
//! .build()
//! .unwrap();
//!
@@ -39,7 +39,7 @@
//! use std::io;
//! use std::io::Read;
//!
-//! let g = GraphBuilder::new_directed(Some("example".to_string()))
+//! let g = GraphBuilder::new_named_directed("example")
//! .add_node(Node::new("N0".to_string()))
//! .add_node(Node::new("N1".to_string()))
//! .add_edge(Edge::new("N0".to_string(), "N1".to_string()))
@@ -74,10 +74,10 @@
//! use std::io;
//! use std::io::Read;
//!
-//! let cluster_0 = SubGraphBuilder::new(Some("cluster_0".to_string()))
+//! let cluster_0 = SubGraphBuilder::new_named("cluster_0")
//! .add_graph_attributes(
//! GraphAttributeStatementBuilder::new()
-//! .label("process #1".to_string())
+//! .label("process #1")
//! .style(GraphStyle::Filled)
//! .color(Color::Named("lightgrey"))
//! .build()
@@ -90,16 +90,16 @@
//! .build()
//! .unwrap(),
//! )
-//! .add_edge(Edge::new("a0".to_string(), "a1".to_string()))
-//! .add_edge(Edge::new("a1".to_string(), "a2".to_string()))
-//! .add_edge(Edge::new("a2".to_string(), "a3".to_string()))
+//! .add_edge(Edge::new("a0", "a1"))
+//! .add_edge(Edge::new("a1", "a2"))
+//! .add_edge(Edge::new("a2", "a3"))
//! .build()
//! .unwrap();
//!
-//! let cluster_1 = SubGraphBuilder::new(Some("cluster_1".to_string()))
+//! let cluster_1 = SubGraphBuilder::new_named("cluster_1")
//! .add_graph_attributes(
//! GraphAttributeStatementBuilder::new()
-//! .label("process #2".to_string())
+//! .label("process #2")
//! .style(GraphStyle::Filled)
//! .color(Color::Named("blue"))
//! .build()
@@ -111,13 +111,13 @@
//! .build()
//! .unwrap(),
//! )
-//! .add_edge(Edge::new("b0".to_string(), "b1".to_string()))
-//! .add_edge(Edge::new("b1".to_string(), "b2".to_string()))
-//! .add_edge(Edge::new("b2".to_string(), "b3".to_string()))
+//! .add_edge(Edge::new("b0", "b1"))
+//! .add_edge(Edge::new("b1", "b2"))
+//! .add_edge(Edge::new("b2", "b3"))
//! .build()
//! .unwrap();
//!
-//! let g = GraphBuilder::new_directed(Some("G".to_string()))
+//! let g = GraphBuilder::new_named_directed("G")
//! .add_node(
//! NodeBuilder::new("start".to_string())
//! .shape(Shape::Mdiamond)
@@ -125,20 +125,20 @@
//! .unwrap(),
//! )
//! .add_node(
-//! NodeBuilder::new("end".to_string())
+//! NodeBuilder::new("end")
//! .shape(Shape::Msquare)
//! .build()
//! .unwrap(),
//! )
//! .add_sub_graph(cluster_0)
//! .add_sub_graph(cluster_1)
-//! .add_edge(Edge::new("start".to_string(), "a0".to_string()))
-//! .add_edge(Edge::new("start".to_string(), "b0".to_string()))
-//! .add_edge(Edge::new("a1".to_string(), "b3".to_string()))
-//! .add_edge(Edge::new("b2".to_string(), "a3".to_string()))
-//! .add_edge(Edge::new("a3".to_string(), "a0".to_string()))
-//! .add_edge(Edge::new("a3".to_string(), "end".to_string()))
-//! .add_edge(Edge::new("b3".to_string(), "end".to_string()))
+//! .add_edge(Edge::new("start", "a0"))
+//! .add_edge(Edge::new("start", "b0"))
+//! .add_edge(Edge::new("a1", "b3"))
+//! .add_edge(Edge::new("b2", "a3"))
+//! .add_edge(Edge::new("a3", "a0"))
+//! .add_edge(Edge::new("a3", "end"))
+//! .add_edge(Edge::new("b3", "end"))
//! .build();
//! ```
//!