summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2019-09-19 09:17:22 +0300
committerLars Wirzenius <liw@liw.fi>2019-09-19 09:52:35 +0300
commita3559c97d9de83c8841354fbdf3c5a38fa25f046 (patch)
tree58897c272a5b0716721e5ca4bce3e9d3f86d64d3 /src
parent446e0f28bdd640f26def54ad069baa1c9cc9ec41 (diff)
downloadroadmap-a3559c97d9de83c8841354fbdf3c5a38fa25f046.tar.gz
Change: implement Roadmap::as_dot
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs47
1 files changed, 36 insertions, 11 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 760b0d2..e1d7b49 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,22 +12,28 @@
//! # use roadmap::Step;
//! # fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
//! let mut r = roadmap::Roadmap::new();
-//! assert_eq!(r.steps().len(), 0);
+//! assert_eq!(r.step_names().len(), 0);
//!
-//! let endgoal = roadmap::Step::new("endgoal", "the end goal");
+//! let mut endgoal = roadmap::Step::new("endgoal", "the end goal");
+//! endgoal.add_dependency("first");
//! assert_eq!(endgoal.name(), "endgoal");
//! assert_eq!(endgoal.label(), "the end goal");
-//! r.add_step(&endgoal)?;
-//! assert_eq!(r.steps().len(), 1);
+//! assert_eq!(endgoal.dependencies(), vec!["first"]);
//!
//! let first = roadmap::Step::new("first", "the first step");
+//!
+//!
+//! r.add_step(&endgoal)?;
+//! assert_eq!(r.step_names().len(), 1);
//! r.add_step(&first)?;
-//! assert_eq!(r.steps().len(), 2);
+//! assert_eq!(r.step_names().len(), 2);
//!
-//! if let Some(step) = r.get_step("endgoal") {
-//! step.add_dependency("first");
-//! assert_eq!(endgoal.dependencies(), vec!["first"]);
+//! assert_eq!(r.as_dot()?, r#"digraph "roadmap" {
+//! endgoal [label="the end goal"];
+//! first [label="the first step"];
+//! first -> endgoal;
//! }
+//! "#.to_string());
//! # Ok(())
//! # }
//! ```
@@ -61,7 +67,7 @@ impl Step {
}
/// Return vector of names of dependencies for a step.
- pub fn dependencies(self) -> Vec<String> {
+ pub fn dependencies(&self) -> Vec<String> {
self.depends.clone()
}
@@ -88,7 +94,7 @@ impl Roadmap {
}
/// Return list of step names.
- pub fn steps<'a>(&'a self) -> Vec<&'a str> {
+ pub fn step_names<'a>(&'a self) -> Vec<&'a str> {
let mut names = vec![];
for step in self.steps.iter() {
names.push(step.name());
@@ -112,6 +118,25 @@ impl Roadmap {
/// is the textual representation, and the caller needs to use the
/// Graphviz dot(1) tool to create an image from it.
pub fn as_dot(self) -> Result<String, Box<dyn std::error::Error>> {
- Ok("".to_string())
+ let labels = self.steps.iter().map(|step|
+ format!("{} [label=\"{}\"];\n", step.name(), step.label())
+ );
+
+ let mut dot = String::new();
+ dot.push_str("digraph \"roadmap\" {\n");
+ for line in labels {
+ dot.push_str(&line);
+ }
+
+ for step in self.steps.iter() {
+ for dep in step.dependencies() {
+ let line = format!("{} -> {};\n", dep, step.name());
+ dot.push_str(&line);
+ }
+ }
+
+ dot.push_str("}\n");
+
+ Ok(dot)
}
}