use crate::{
node::{Node},
edge::{Edge, edge},
style::{Style},
id::{Id, id_name},
};
use std::borrow::Cow;
pub type Nodes<'a,N> = Cow<'a,[N]>;
pub trait GraphWalk<'a, N: Clone> {
fn nodes(&'a self) -> Vec<&Node>;
fn edges(&'a self) -> Vec<&Edge>;
fn graph_id(&'a self) -> Id<'a>;
#[inline]
fn kind(&self) -> Kind {
Kind::Digraph
}
}
pub struct LabelledGraph {
pub name: &'static str,
pub node_labels: Vec<Option<String>>,
pub node_styles: Vec<Style>,
edges: Vec<Edge>,
nodes: Vec<Node>
}
impl LabelledGraph {
pub fn new(name: &'static str,
node_labels: Vec<Option<&str>>,
edges: Vec<Edge>,
node_styles: Option<Vec<Style>>)
-> LabelledGraph {
let count = node_labels.len();
let mut nodes: Vec<Node> = vec![];
for i in 0..count {
let node_label = match node_labels[i] {
Some(ref l) => (*l.clone()).into(),
None => id_name(&i).name().to_string(),
};
let node_style = match node_styles {
Some(ref styles) => styles[i],
None => Style::None,
};
let node: Node = Node::new(id_name(&i).as_slice(), &node_label, node_style, None, None);
nodes.push(node);
};
let mut new_node_labels: Vec<Option<String>> = vec![];
for s in node_labels {
match s {
Some(st) => new_node_labels.push(Some(String::from(st))),
None => new_node_labels.push(None)
}
}
LabelledGraph {
name: name,
node_labels: new_node_labels,
edges: edges,
node_styles: match node_styles {
Some(nodes) => nodes,
None => vec![Style::None; count],
},
nodes: nodes
}
}
}
pub fn new_graph(
name: &'static str,
nodes: Vec<Node>,
edges: Vec<Edge>,
node_styles: Option<Vec<Style>>)
-> LabelledGraph {
let node_labels: Vec<Option<String>> = nodes.iter().map(|n| Some(n.name.clone())).collect();
LabelledGraph {
name: name,
node_labels: node_labels,
edges: edges,
node_styles: match node_styles {
Some(nodes) => nodes,
None => vec![Style::None; nodes.len()],
},
nodes: nodes
}
}
impl<'a> GraphWalk<'a, Node> for LabelledGraph {
fn nodes(&'a self) -> Vec<&Node> {
self.nodes.iter().map(|node| node).collect()
}
fn edges(&'a self) -> Vec<&Edge> {
self.edges.iter().collect()
}
fn graph_id(&'a self) -> Id<'a> {
Id::new(&self.name[..]).unwrap()
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Kind {
Digraph,
Graph,
}
impl Kind {
pub fn keyword(&self) -> &'static str {
match *self {
Kind::Digraph => "digraph",
Kind::Graph => "graph"
}
}
pub fn edgeop(&self) -> &'static str {
match *self {
Kind::Digraph => "->",
Kind::Graph => "--",
}
}
}
pub type SimpleEdge = (usize, usize);
pub struct DefaultStyleGraph {
name: &'static str,
edges: Vec<Edge>,
kind: Kind,
node_vec: Vec<Node>
}
impl DefaultStyleGraph {
pub fn new(name: &'static str,
nodes: usize,
edges: Vec<SimpleEdge>,
kind: Kind)
-> DefaultStyleGraph {
assert!(!name.is_empty());
let mut results: Vec<Edge> = vec![];
for (start, end) in edges.iter() {
let edge = edge(id_name(start).as_slice(), id_name(end).as_slice(), "", Style::None, None);
results.push(edge);
}
DefaultStyleGraph {
name: name,
edges: results,
kind: kind,
node_vec: (0..nodes).map(|index| Node::new(id_name(&index).as_slice(), id_name(&index).as_slice(), Style::None, None, None)).collect()
}
}
}
impl<'a> GraphWalk<'a, Node> for DefaultStyleGraph {
fn nodes(&'a self) -> Vec<&Node> {
self.node_vec.iter().collect()
}
fn edges(&'a self) -> Vec<&Edge> {
self.edges.iter().collect()
}
fn graph_id(&'a self) -> Id<'a> {
Id::new(&self.name[..]).unwrap()
}
fn kind(&self) -> Kind {
self.kind
}
}