diff options
Diffstat (limited to 'src/parser.rs')
-rw-r--r-- | src/parser.rs | 101 |
1 files changed, 8 insertions, 93 deletions
diff --git a/src/parser.rs b/src/parser.rs index 6cc3d25..8c7a9c1 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,4 +1,3 @@ -use serde_yaml::Value; use std::collections::HashMap; pub use crate::Roadmap; @@ -9,121 +8,37 @@ pub use crate::Step; /// Create a new roadmap from a textual YAML representation. pub fn from_yaml(yaml: &str) -> RoadmapResult<Roadmap> { - let mut roadmap = Roadmap::new(); - let map: HashMap<String, serde_yaml::Value> = serde_yaml::from_str(yaml)?; - - for (name, value) in map { - let step = step_from_value(&name, &value)?; - roadmap.add_step(step); + let mut roadmap: HashMap<String, Step> = serde_yaml::from_str(yaml)?; + for (name, step) in roadmap.iter_mut() { + step.set_name(name); } - + let roadmap = Roadmap::new(roadmap); roadmap.validate()?; Ok(roadmap) } -// Convert a Value into a Step, if possible. -fn step_from_value(name: &str, value: &Value) -> RoadmapResult<Step> { - match value { - Value::Mapping(_) => { - let label = parse_label(value); - let status = parse_status(value)?; - - let mut step = Step::new(name, label); - step.set_status(status); - - for depname in parse_depends(value)?.iter() { - step.add_dependency(depname); - } - - Ok(step) - } - _ => Err(RoadmapError::StepNotMapping), - } -} - -// Get a sequence of depenencies. -fn parse_depends(map: &Value) -> RoadmapResult<Vec<&str>> { - let key_name = "depends"; - let key = Value::String(key_name.to_string()); - let mut depends: Vec<&str> = vec![]; - - match map.get(&key) { - None => (), - Some(Value::Sequence(deps)) => { - for depname in deps.iter() { - match depname { - Value::String(depname) => depends.push(depname), - _ => return Err(RoadmapError::DependsNotNames), - } - } - } - _ => return Err(RoadmapError::DependsNotNames), - } - - Ok(depends) -} - -// Get label string from a Mapping element, or empty string. -fn parse_label(map: &Value) -> &str { - parse_string("label", map) -} - -// Get status string from a Mapping element. Default to unknown status. -fn parse_status(map: &Value) -> RoadmapResult<Status> { - let text = parse_string("status", map); - match Status::from_text(text) { - Some(status) => Ok(status), - _ => Err(RoadmapError::UnknownStatus(text.into())), - } -} - -// Get string value from a Mapping field, or empty string if field -// isn't there. -fn parse_string<'a>(key_name: &str, map: &'a Value) -> &'a str { - let key = Value::String(key_name.to_string()); - match map.get(&key) { - Some(Value::String(s)) => s, - _ => "", - } -} - #[cfg(test)] mod tests { use super::from_yaml; #[test] fn yaml_is_empty() { - if from_yaml("").is_ok() { - panic!("expected a parse error"); - } + assert!(from_yaml("").is_err()); } #[test] fn yaml_is_list() { - if from_yaml("[]").is_ok() { - panic!("expected a parse error"); - } - } - - #[test] - fn yaml_map_entries_not_maps() { - if from_yaml("foo: []").is_ok() { - panic!("expected a parse error"); - } + assert!(from_yaml("[]").is_err()); } #[test] fn yaml_unknown_dep() { - if from_yaml("foo: {depends: [bar]}").is_ok() { - panic!("expected a parse error"); - } + assert!(from_yaml("foo: {depends: [bar]}").is_err()); } #[test] fn yaml_unknown_status() { - if from_yaml(r#"foo: {status: "bar"}"#).is_ok() { - panic!("expected a parse error"); - } + assert!(from_yaml(r#"foo: {status: "bar"}"#).is_err()); } #[test] |