//! dot::render(&edges, output).unwrap()
//! }
//!
-//! impl<'a> dot::Labeller<'a, Nd, Ed> for Edges {
+//! impl<'a> dot::Labeller<'a> for Edges {
+//! type Node = Nd;
+//! type Edge = Ed;
//! fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example1").unwrap() }
//!
//! fn node_id(&'a self, n: &Nd) -> dot::Id<'a> {
//! }
//! }
//!
-//! impl<'a> dot::GraphWalk<'a, Nd, Ed> for Edges {
+//! impl<'a> dot::GraphWalk<'a> for Edges {
+//! type Node = Nd;
+//! type Edge = Ed;
//! fn nodes(&self) -> dot::Nodes<'a,Nd> {
//! // (assumes that |N| \approxeq |E|)
//! let &Edges(ref v) = self;
//! dot::render(&graph, output).unwrap()
//! }
//!
-//! impl<'a> dot::Labeller<'a, Nd, Ed<'a>> for Graph {
+//! impl<'a> dot::Labeller<'a> for Graph {
+//! type Node = Nd;
+//! type Edge = Ed<'a>;
//! fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example2").unwrap() }
//! fn node_id(&'a self, n: &Nd) -> dot::Id<'a> {
//! dot::Id::new(format!("N{}", n)).unwrap()
//! }
//! }
//!
-//! impl<'a> dot::GraphWalk<'a, Nd, Ed<'a>> for Graph {
+//! impl<'a> dot::GraphWalk<'a> for Graph {
+//! type Node = Nd;
+//! type Edge = Ed<'a>;
//! fn nodes(&self) -> dot::Nodes<'a,Nd> { (0..self.nodes.len()).collect() }
//! fn edges(&'a self) -> dot::Edges<'a,Ed<'a>> { self.edges.iter().collect() }
//! fn source(&self, e: &Ed) -> Nd { let & &(s,_) = e; s }
//! dot::render(&graph, output).unwrap()
//! }
//!
-//! impl<'a> dot::Labeller<'a, Nd<'a>, Ed<'a>> for Graph {
+//! impl<'a> dot::Labeller<'a> for Graph {
+//! type Node = Nd<'a>;
+//! type Edge = Ed<'a>;
//! fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example3").unwrap() }
//! fn node_id(&'a self, n: &Nd<'a>) -> dot::Id<'a> {
//! dot::Id::new(format!("N{}", n.0)).unwrap()
//! }
//! }
//!
-//! impl<'a> dot::GraphWalk<'a, Nd<'a>, Ed<'a>> for Graph {
+//! impl<'a> dot::GraphWalk<'a> for Graph {
+//! type Node = Nd<'a>;
+//! type Edge = Ed<'a>;
//! fn nodes(&'a self) -> dot::Nodes<'a,Nd<'a>> {
//! self.nodes.iter().map(|s| &s[..]).enumerate().collect()
//! }
/// The graph instance is responsible for providing the DOT compatible
/// identifiers for the nodes and (optionally) rendered labels for the nodes and
/// edges, as well as an identifier for the graph itself.
-pub trait Labeller<'a,N,E> {
+pub trait Labeller<'a> {
+ type Node;
+ type Edge;
+
/// Must return a DOT compatible identifier naming the graph.
fn graph_id(&'a self) -> Id<'a>;
/// Maps `n` to a unique identifier with respect to `self`. The
/// implementor is responsible for ensuring that the returned name
/// is a valid DOT identifier.
- fn node_id(&'a self, n: &N) -> Id<'a>;
+ fn node_id(&'a self, n: &Self::Node) -> Id<'a>;
/// Maps `n` to one of the [graphviz `shape` names][1]. If `None`
/// is returned, no `shape` attribute is specified.
///
/// [1]: http://www.graphviz.org/content/node-shapes
- fn node_shape(&'a self, _node: &N) -> Option<LabelText<'a>> {
+ fn node_shape(&'a self, _node: &Self::Node) -> Option<LabelText<'a>> {
None
}
/// Maps `n` to a label that will be used in the rendered output.
/// The label need not be unique, and may be the empty string; the
/// default is just the output from `node_id`.
- fn node_label(&'a self, n: &N) -> LabelText<'a> {
+ fn node_label(&'a self, n: &Self::Node) -> LabelText<'a> {
LabelStr(self.node_id(n).name)
}
/// Maps `e` to a label that will be used in the rendered output.
/// The label need not be unique, and may be the empty string; the
/// default is in fact the empty string.
- fn edge_label(&'a self, e: &E) -> LabelText<'a> {
+ fn edge_label(&'a self, e: &Self::Edge) -> LabelText<'a> {
let _ignored = e;
LabelStr("".into_cow())
}
/// Maps `n` to a style that will be used in the rendered output.
- fn node_style(&'a self, _n: &N) -> Style {
+ fn node_style(&'a self, _n: &Self::Node) -> Style {
Style::None
}
/// Maps `e` to a style that will be used in the rendered output.
- fn edge_style(&'a self, _e: &E) -> Style {
+ fn edge_style(&'a self, _e: &Self::Edge) -> Style {
Style::None
}
}
/// `Cow<[T]>` to leave implementors the freedom to create
/// entirely new vectors or to pass back slices into internally owned
/// vectors.
-pub trait GraphWalk<'a, N: Clone, E: Clone> {
+pub trait GraphWalk<'a> {
+ type Node: Clone;
+ type Edge: Clone;
+
/// Returns all the nodes in this graph.
- fn nodes(&'a self) -> Nodes<'a, N>;
+ fn nodes(&'a self) -> Nodes<'a, Self::Node>;
/// Returns all of the edges in this graph.
- fn edges(&'a self) -> Edges<'a, E>;
+ fn edges(&'a self) -> Edges<'a, Self::Edge>;
/// The source node for `edge`.
- fn source(&'a self, edge: &E) -> N;
+ fn source(&'a self, edge: &Self::Edge) -> Self::Node;
/// The target node for `edge`.
- fn target(&'a self, edge: &E) -> N;
+ fn target(&'a self, edge: &Self::Edge) -> Self::Node;
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
/// Renders directed graph `g` into the writer `w` in DOT syntax.
/// (Simple wrapper around `render_opts` that passes a default set of options.)
-pub fn render<'a,
- N: Clone + 'a,
- E: Clone + 'a,
- G: Labeller<'a, N, E> + GraphWalk<'a, N, E>,
- W: Write>
- (g: &'a G,
- w: &mut W)
- -> io::Result<()> {
+pub fn render<'a,N,E,G,W>(g: &'a G, w: &mut W) -> io::Result<()>
+ where N: Clone + 'a,
+ E: Clone + 'a,
+ G: Labeller<'a, Node=N, Edge=E> + GraphWalk<'a, Node=N, Edge=E>,
+ W: Write
+{
render_opts(g, w, &[])
}
/// Renders directed graph `g` into the writer `w` in DOT syntax.
/// (Main entry point for the library.)
-pub fn render_opts<'a,
- N: Clone + 'a,
- E: Clone + 'a,
- G: Labeller<'a, N, E> + GraphWalk<'a, N, E>,
- W: Write>
- (g: &'a G,
- w: &mut W,
- options: &[RenderOption])
- -> io::Result<()> {
+pub fn render_opts<'a, N, E, G, W>(g: &'a G,
+ w: &mut W,
+ options: &[RenderOption])
+ -> io::Result<()>
+ where N: Clone + 'a,
+ E: Clone + 'a,
+ G: Labeller<'a, Node=N, Edge=E> + GraphWalk<'a, Node=N, Edge=E>,
+ W: Write
+{
fn writeln<W: Write>(w: &mut W, arg: &[&str]) -> io::Result<()> {
for &s in arg {
try!(w.write_all(s.as_bytes()));
Id::new(format!("N{}", *n)).unwrap()
}
- impl<'a> Labeller<'a, Node, &'a Edge> for LabelledGraph {
+ impl<'a> Labeller<'a> for LabelledGraph {
+ type Node = Node;
+ type Edge = &'a Edge;
fn graph_id(&'a self) -> Id<'a> {
Id::new(&self.name[..]).unwrap()
}
}
}
- impl<'a> Labeller<'a, Node, &'a Edge> for LabelledGraphWithEscStrs {
+ impl<'a> Labeller<'a> for LabelledGraphWithEscStrs {
+ type Node = Node;
+ type Edge = &'a Edge;
fn graph_id(&'a self) -> Id<'a> {
self.graph.graph_id()
}
}
}
- impl<'a> GraphWalk<'a, Node, &'a Edge> for LabelledGraph {
+ impl<'a> GraphWalk<'a> for LabelledGraph {
+ type Node = Node;
+ type Edge = &'a Edge;
fn nodes(&'a self) -> Nodes<'a, Node> {
(0..self.node_labels.len()).collect()
}
}
}
- impl<'a> GraphWalk<'a, Node, &'a Edge> for LabelledGraphWithEscStrs {
+ impl<'a> GraphWalk<'a> for LabelledGraphWithEscStrs {
+ type Node = Node;
+ type Edge = &'a Edge;
fn nodes(&'a self) -> Nodes<'a, Node> {
self.graph.nodes()
}