From 5122f63f07f2893abdad11937e9842c7d38baffa Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sat, 5 Oct 2019 10:49:05 +0300 Subject: Change: set README file type via Emacs mode line --- README | 2 + src/#parser.rs# | 170 -------------------------------------------------------- src/.#parser.rs | 1 - 3 files changed, 2 insertions(+), 171 deletions(-) delete mode 100644 src/#parser.rs# delete mode 120000 src/.#parser.rs diff --git a/README b/README index 438c321..e347562 100644 --- a/README +++ b/README @@ -1,3 +1,5 @@ +-*-markdown-*- + Produce directed acyclic graph representations of a project roadmap. The idea is to show the steps needed to reach a goal, and the order they need to be taken, but ignore due dates and other irrelevant diff --git a/src/#parser.rs# b/src/#parser.rs# deleted file mode 100644 index 32cdd73..0000000 --- a/src/#parser.rs# +++ /dev/null @@ -1,170 +0,0 @@ -use serde_yaml; -use serde_yaml::Value; -use std::collections::HashMap -pub use crate::Roadmap; -pub use crate::RoadmapResult; -pub use crate::Status; -pub use crate::Step; - -/// Create a new roadmap from a textual YAML representation. -pub fn from_yaml(yaml: &str) -> RoadmapResult { - let mut roadmap = Roadmap::new(); - let map: HashMap = serde_yaml::from_str(yaml)?; - - for (name, value) in map { - let step = step_from_value(&name, &value)?; - roadmap.add_step(step); - } - - roadmap.validate()?; - Ok(roadmap) -} - -// Convert a Value into a Step, if possible. -fn step_from_value(name: &str, value: &Value) -> RoadmapResult { - 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("step is not a mapping".to_string().into()), - } -} - -// Get a sequence of depenencies. -fn parse_depends(map: &Value) -> RoadmapResult> { - let key_name = "depends"; - let key = Value::String(key_name.to_string()); - let mut depends: Vec<&str> = vec![]; - let need_list_of_names = format!("'depends' must be a list of step names"); - - match map.get(&key) { - None => (), - Some(Value::Sequence(deps)) => { - for depname in deps.iter() { - match depname { - Value::String(depname) => depends.push(depname), - _ => return Err(need_list_of_names.into()), - } - } - } - _ => return Err(need_list_of_names.into()), - } - - 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<'a>(map: &'a Value) -> RoadmapResult { - let text = parse_string("status", map); - match Status::from_text(text) { - Some(status) => Ok(status), - _ => Err(format!("unknown status: {:?}", 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() { - let r = from_yaml(""); - match r { - Ok(_) => panic!("expected a parse error"), - _ => (), - } - } - - #[test] - fn yaml_is_list() { - let r = from_yaml("[]"); - match r { - Ok(_) => panic!("expected a parse error"), - _ => (), - } - } - - #[test] - fn yaml_map_entries_not_maps() { - let r = from_yaml("foo: []"); - match r { - Ok(_) => panic!("expected a parse error"), - _ => (), - } - } - - #[test] - fn yaml_unknown_dep() { - let r = from_yaml("foo: {depends: [bar]}"); - match r { - Ok(_) => panic!("expected a parse error"), - _ => (), - } - } - - #[test] - fn yaml_unknown_status() { - let r = from_yaml(r#"foo: {status: "bar"}"#); - match r { - Ok(_) => panic!("expected a parse error"), - _ => (), - } - } - - #[test] - fn yaml_happy() { - let roadmap = from_yaml( - " -first: - label: the first step -second: - label: the second step - depends: - - first -", - ) - .unwrap(); - - let names: Vec<&str> = roadmap.step_names().collect(); - 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 deps: Vec<&str> = first.dependencies().collect(); - assert_eq!(deps.len(), 0); - - let second = roadmap.get_step("second").unwrap(); - assert_eq!(second.name(), "second"); - assert_eq!(second.label(), "the second step"); - let deps: Vec<&str> = second.dependencies().collect(); - assert_eq!(deps, vec!["first"]); - } -} diff --git a/src/.#parser.rs b/src/.#parser.rs deleted file mode 120000 index 5d257a5..0000000 --- a/src/.#parser.rs +++ /dev/null @@ -1 +0,0 @@ -liw@exolobe1.5169:1568966750 \ No newline at end of file -- cgit v1.2.1