summaryrefslogtreecommitdiff
path: root/src/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.rs')
-rw-r--r--src/parser.rs101
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]