summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2019-09-20 10:10:48 +0300
committerLars Wirzenius <liw@liw.fi>2019-09-20 10:10:48 +0300
commit133228357f8cf62f29ad85cc23ad1590ef2ca4e9 (patch)
treed82d7c54c611d5eecf38bb48cf239be5582db28d /src
parent1df087c14691674449a34dbee96491e2089ffb82 (diff)
downloadroadmap-133228357f8cf62f29ad85cc23ad1590ef2ca4e9.tar.gz
Change: moar parsing
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs55
1 files changed, 53 insertions, 2 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 6886727..3fa9d38 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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");
+ }
}