diff options
author | Lars Wirzenius <liw@liw.fi> | 2019-09-23 10:45:45 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2019-09-23 10:45:45 +0300 |
commit | 804c418bbfba696020957f5f22aa30660302b744 (patch) | |
tree | ba296e779b1ba65faab49b9cce13cb7b10baff15 /src/lib.rs | |
parent | 2936f3cf609bff77ef0851ebf55b35c74d31a67a (diff) | |
download | roadmap-804c418bbfba696020957f5f22aa30660302b744.tar.gz |
Add: support for color and shape for steps
These must currently be specified in the YAML directly.
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 69 |
1 files changed, 64 insertions, 5 deletions
@@ -38,6 +38,7 @@ use textwrap::fill; #[derive(Clone)] pub struct Step { name: String, + status: String, label: String, depends: Vec<String>, } @@ -47,6 +48,7 @@ impl Step { pub fn new(name: &str, label: &str) -> Step { Step { name: name.to_string(), + status: "".to_string(), label: label.to_string(), depends: vec![], } @@ -62,6 +64,17 @@ impl Step { &self.label } + /// Return the status of a step. + pub fn status<'a>(&'a self) -> &'a str { + &self.status + } + + /// Set the status of a step. + pub fn set_status(&mut self, status: &str) { + eprintln!("xxx setting status to {} for {}", status, self.label()); + self.status = String::from(status); + } + /// Return vector of names of dependencies for a step. pub fn dependencies(&self) -> impl Iterator<Item = &String> { self.depends.iter() @@ -69,7 +82,7 @@ impl Step { /// Add the name of a dependency to step. pub fn add_dependency(&mut self, name: &str) { - self.depends.push(name.to_string()); + self.depends.push(String::from(name)); } } @@ -94,18 +107,30 @@ impl Roadmap { roadmap.add_step(&step)?; } + for name in roadmap.step_names() { + let step = roadmap.get_step(name).unwrap(); + eprintln!("roadmap step {} ({}) status {}", name, step.name(), step.status()); + } + Ok(roadmap) } // Convert a Value into a Step, if possible. fn step_from_value(name: &str, value: &Value) -> Result<Step, &'static str> { let label_key = Value::String("label".to_string()); + let status_key = Value::String("status".to_string()); let deps_key = Value::String("depends".to_string()); + eprintln!("=====\nstep_from_value: {:?}", value); match value { Value::Mapping(map) => { if let Some(Value::String(label)) = map.get(&label_key) { let mut step = Step::new(name, label); + if let Some(Value::String(status)) = map.get(&status_key) { + eprintln!("step_from_value: status: {:?}", status); + step.set_status(&status); + eprintln!("status from step: {:?}", step.status()); + } if let Some(Value::Sequence(deps)) = map.get(&deps_key) { for depname in deps.iter() { if let Value::String(depname) = depname { @@ -163,9 +188,11 @@ impl Roadmap { pub fn as_dot(self, label_width: usize) -> Result<String, Box<dyn std::error::Error>> { let labels = self.steps.iter().map(|step| { format!( - "{} [label=\"{}\"];\n", + "{} [label=\"{}\" style=filled fillcolor=\"{}\" shape=\"{}\"];\n", step.name(), - fill(&step.label(), label_width).replace("\n", "\\n") + fill(&step.label(), label_width).replace("\n", "\\n"), + Roadmap::get_status_color(step), + Roadmap::get_status_shape(step), ) }); @@ -186,6 +213,30 @@ impl Roadmap { Ok(dot) } + + fn get_status_color(step: &Step) -> &str { +// eprintln!("color for {}: {}", step.status(), step.label()); + match step.status() { + "blocked" => "#f4bada", + "finished" => "#eeeeee", + "ready" => "#ffffff", + "next" => "#0cc00", + "goal" => "#00eeee", + _ => "unknownstatus", + } + } + + fn get_status_shape(step: &Step) -> &str { +// eprintln!("shape for {}", step.status()); + match step.status() { + "blocked" => "rectangle", + "finished" => "circle", + "ready" => "ellipse", + "next" => "ellipse", + "goal" => "diamond", + _ => "unknownshape", + } + } } #[cfg(test)] @@ -196,11 +247,19 @@ mod tests { fn new_step() { let step = Step::new("myname", "my label"); assert_eq!(step.name(), "myname"); + assert_eq!(step.status(), "goal"); assert_eq!(step.label(), "my label"); assert_eq!(step.dependencies().count(), 0); } #[test] + fn set_status() { + let mut step = Step::new("myname", "my label"); + step.set_status("next"); + assert_eq!(step.status(), "next"); + } + + #[test] fn add_step_dependency() { let mut second = Step::new("second", "the second step"); second.add_dependency("first"); @@ -255,8 +314,8 @@ mod tests { assert_eq!( roadmap.as_dot(999).unwrap(), "digraph \"roadmap\" { -first [label=\"\"]; -second [label=\"\"]; +first [label=\"\" fillcolor=\"#ffffff\" shape=\"ellipse\"]; +second [label=\"\" fillcolor=\"#00eeeeee\" shape=\"diamond\"]; first -> second; } " |