diff options
author | Lars Wirzenius <liw@liw.fi> | 2019-09-20 10:10:48 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2019-09-20 10:10:48 +0300 |
commit | 133228357f8cf62f29ad85cc23ad1590ef2ca4e9 (patch) | |
tree | d82d7c54c611d5eecf38bb48cf239be5582db28d /src | |
parent | 1df087c14691674449a34dbee96491e2089ffb82 (diff) | |
download | roadmap-133228357f8cf62f29ad85cc23ad1590ef2ca4e9.tar.gz |
Change: moar parsing
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 55 |
1 files changed, 53 insertions, 2 deletions
@@ -38,6 +38,10 @@ //! # } //! ``` +use std::collections::HashMap; +use serde_yaml; +use serde_yaml::Value; + /// A step in a roadmap. #[derive(Clone)] pub struct Step { @@ -89,8 +93,30 @@ impl Roadmap { } /// Create a new roadmap from a YAML representation. - pub fn from_yaml(_yaml: &str) -> Result<Roadmap, Box<dyn std::error::Error>> { - Ok(Roadmap::new()) + pub fn from_yaml(yaml: &str) -> Result<Roadmap, Box<dyn std::error::Error>> { + let mut roadmap = Roadmap::new(); + let map: HashMap<String, serde_yaml::Value> = serde_yaml::from_str(yaml)?; + + for (name, value) in map { + let step = Roadmap::step_from_value(&name, &value)?; + roadmap.add_step(&step)?; + } + + 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()); + match value { + Value::Mapping(map) => { + if let Some(Value::String(label)) = map.get(&label_key) { + return Ok(Step::new(name, label)); + } + Ok(Step::new(name, "")) + }, + _ => Err("step is not a mapping"), + } } /// Return list of step names. @@ -231,4 +257,29 @@ first -> second; let roadmap = Roadmap::from_yaml("{}").unwrap(); assert_eq!(roadmap.step_names().len(), 0); } + + #[test] + fn from_nonempty_yaml() { + let mut roadmap = Roadmap::from_yaml(" +first: + label: the first step +second: + label: the second step + depends: + - first +").unwrap(); + + let names = roadmap.step_names(); + assert_eq!(names.len(), 2); + assert!(names.contains(&"first")); + assert!(names.contains(&"second")); + + let first = roadmap.get_step("first").unwrap(); + assert_eq!(first.name(), "first"); + assert_eq!(first.label(), "the first step"); + + let second = roadmap.get_step("second").unwrap(); + assert_eq!(second.name(), "second"); + assert_eq!(second.label(), "the second step"); + } } |