From 2ac507be31bc0dd2aab4c2f9bdc7cd7bfbd8298e Mon Sep 17 00:00:00 2001 From: kdesjard Date: Thu, 7 Dec 2023 15:48:58 +0000 Subject: [PATCH 1/6] add new function to Parser trait to read tasks from a string slice. add an impl to convert io errors to parse errors Signed-off-by: kdesjard --- src/utils/parser.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/utils/parser.rs b/src/utils/parser.rs index 40a6dbb..99c87d5 100644 --- a/src/utils/parser.rs +++ b/src/utils/parser.rs @@ -25,6 +25,12 @@ pub trait Parser { file: &str, specific_actions: HashMap, ) -> Result>, ParseError>; + + fn parse_tasks_from_str( + &self, + content: &str, + specific_actions: HashMap, + ) -> Result>, ParseError>; } /// Errors that may occur during configuration file parsing. @@ -40,3 +46,9 @@ impl From for ParseError { ParseError(value) } } + +impl From for ParseError { + fn from(value: std::io::Error) -> Self { + ParseError(value.to_string()) + } +} From 590443f2941eb78de69799a3d1164bde76ae3467 Mon Sep 17 00:00:00 2001 From: kdesjard Date: Thu, 7 Dec 2023 15:49:37 +0000 Subject: [PATCH 2/6] move load_file into separate module Signed-off-by: kdesjard --- src/utils/file.rs | 10 ++++++++++ src/utils/mod.rs | 1 + 2 files changed, 11 insertions(+) create mode 100644 src/utils/file.rs diff --git a/src/utils/file.rs b/src/utils/file.rs new file mode 100644 index 0000000..9cf059d --- /dev/null +++ b/src/utils/file.rs @@ -0,0 +1,10 @@ +use std::fs::File; +use std::io::{Read,Error}; + +/// Given file path, and load configuration file. +pub fn load_file(file: &str) -> Result { + let mut content = String::new(); + let mut fh = File::open(file)?; + fh.read_to_string(&mut content)?; + Ok(content) +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 28eb5c2..a790b68 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -5,6 +5,7 @@ mod env; mod parser; +pub mod file; pub use self::env::EnvVar; pub use self::parser::{ParseError, Parser}; From 656b9acb95349b92410381a20f465727b8881366 Mon Sep 17 00:00:00 2001 From: kdesjard Date: Thu, 7 Dec 2023 15:50:07 +0000 Subject: [PATCH 3/6] remove load_file and allow for loading of yaml from a file or a string slice using the updated Parser trait Signed-off-by: kdesjard --- src/yaml/yaml_parser.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/yaml/yaml_parser.rs b/src/yaml/yaml_parser.rs index df17870..cda037e 100644 --- a/src/yaml/yaml_parser.rs +++ b/src/yaml/yaml_parser.rs @@ -1,21 +1,14 @@ //! Default yaml configuration file parser. use super::{FileContentError, FileNotFound, YamlTask, YamlTaskError}; -use crate::{utils::ParseError, Action, CommandAction, Parser, Task}; -use std::{collections::HashMap, fs::File, io::Read, sync::Arc}; +use crate::{utils::ParseError, Action, CommandAction, Parser, Task, utils::file::load_file}; +use std::{collections::HashMap, sync::Arc}; use yaml_rust::{Yaml, YamlLoader}; /// An implementation of [`Parser`]. It is the default yaml configuration file parser. pub struct YamlParser; impl YamlParser { - /// Given file path, and load configuration file. - fn load_file(&self, file: &str) -> Result { - let mut content = String::new(); - let mut yaml = File::open(file).map_err(FileNotFound)?; - yaml.read_to_string(&mut content).unwrap(); - Ok(content) - } /// Parses an item in the configuration file into a task. /// An item refers to: /// @@ -63,15 +56,22 @@ impl Parser for YamlParser { fn parse_tasks( &self, file: &str, + specific_actions: HashMap, + ) -> Result>, ParseError> { + let content = load_file(file)?; + self.parse_tasks_from_str(&content,specific_actions) + } + + fn parse_tasks_from_str( + &self, + content: &str, mut specific_actions: HashMap, ) -> Result>, ParseError> { - let content = self.load_file(file)?; // Parse Yaml let yaml_tasks = YamlLoader::load_from_str(&content).map_err(FileContentError::IllegalYamlContent)?; - // empty file error if yaml_tasks.is_empty() { - return Err(FileContentError::Empty(file.to_string()).into()); + return Err(ParseError("No Tasks found".to_string())); } let yaml_tasks = yaml_tasks[0]["dagrs"] .as_hash() From 1965595625def33fd8772b8d70e94857922c8f97 Mon Sep 17 00:00:00 2001 From: kdesjard Date: Thu, 7 Dec 2023 15:50:46 +0000 Subject: [PATCH 4/6] add new functions to handle loading the tasks/content from a string slice Signed-off-by: kdesjard --- src/engine/dag.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/engine/dag.rs b/src/engine/dag.rs index 210fff6..d890520 100644 --- a/src/engine/dag.rs +++ b/src/engine/dag.rs @@ -115,6 +115,17 @@ impl Dag { Dag::read_tasks(file, parser, specific_actions) } + /// Given a yaml configuration file parsing task to generate a dag. + #[cfg(feature = "yaml")] + pub fn with_yaml_str( + content: &str, + specific_actions: HashMap, + ) -> Result { + use crate::YamlParser; + let parser = Box::new(YamlParser); + Dag::read_tasks_from_str(content, parser, specific_actions) + } + /// Generates a dag with the user given path to a custom parser and task config file. pub fn with_config_file_and_parser( file: &str, @@ -124,6 +135,15 @@ impl Dag { Dag::read_tasks(file, parser, specific_actions) } + /// Generates a dag with the user given path to a custom parser and task config file. + pub fn with_config_str_and_parser( + content: &str, + parser: Box, + specific_actions: HashMap, + ) -> Result { + Dag::read_tasks_from_str(content, parser, specific_actions) + } + /// Parse the content of the configuration file into a series of tasks and generate a dag. fn read_tasks( @@ -139,6 +159,21 @@ impl Dag { Ok(dag) } + /// Parse the content of the configuration file into a series of tasks and generate a dag. + + fn read_tasks_from_str( + content: &str, + parser: Box, + specific_actions: HashMap, + ) -> Result { + let tasks = parser.parse_tasks_from_str(content, specific_actions)?; + + let mut dag = Dag::new(); + dag.tasks = tasks.into_iter().map(|task| (task.id(), task)).collect(); + + Ok(dag) + } + /// create rely map between tasks. /// /// This operation will initialize `dagrs.rely_graph` if no error occurs. From c93815b33f591f87bcefc4bf64dd3a512191fc02 Mon Sep 17 00:00:00 2001 From: kdesjard Date: Thu, 7 Dec 2023 15:51:27 +0000 Subject: [PATCH 5/6] update the example to load tasks from directly from a file and indirectly with a string slice Signed-off-by: kdesjard --- examples/yaml_dag.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/yaml_dag.rs b/examples/yaml_dag.rs index e998f5d..a914768 100644 --- a/examples/yaml_dag.rs +++ b/examples/yaml_dag.rs @@ -3,10 +3,16 @@ extern crate dagrs; use dagrs::Dag; +use dagrs::utils::file::load_file; use std::collections::HashMap; fn main() { env_logger::init(); let mut job = Dag::with_yaml("tests/config/correct.yaml", HashMap::new()).unwrap(); assert!(job.start().unwrap()); + + let content = load_file("tests/config/correct.yaml").unwrap(); + let mut job = Dag::with_yaml_str(&content, HashMap::new()).unwrap(); + assert!(job.start().unwrap()); + } From 0590f35445a87666dba385f16c406c6e1541b1fc Mon Sep 17 00:00:00 2001 From: kdesjard Date: Thu, 7 Dec 2023 16:04:32 +0000 Subject: [PATCH 6/6] update the custom parser example Signed-off-by: kdesjard --- examples/custom_parser_and_task.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/examples/custom_parser_and_task.rs b/examples/custom_parser_and_task.rs index d7567fe..7b4c9b4 100644 --- a/examples/custom_parser_and_task.rs +++ b/examples/custom_parser_and_task.rs @@ -82,10 +82,9 @@ impl Display for MyTask { struct ConfigParser; impl ConfigParser { - fn load_file(&self, file: &str) -> Result, ParseError> { + fn load_file(&self, file: &str) -> Result { let contents = fs::read_to_string(file).map_err(|e| e.to_string())?; - let lines: Vec = contents.lines().map(|line| line.to_string()).collect(); - Ok(lines) + Ok(contents) } fn parse_one(&self, item: String) -> MyTask { @@ -109,12 +108,20 @@ impl Parser for ConfigParser { fn parse_tasks( &self, file: &str, - _specific_actions: HashMap, + specific_actions: HashMap, ) -> Result>, ParseError> { let content = self.load_file(file)?; + self.parse_tasks_from_str(&content, specific_actions) + } + fn parse_tasks_from_str( + &self, + content: &str, + _specific_actions: HashMap, + ) -> Result>, ParseError> { + let lines: Vec = content.lines().map(|line| line.to_string()).collect(); let mut map = HashMap::new(); let mut tasks = Vec::new(); - content.into_iter().for_each(|line| { + lines.into_iter().for_each(|line| { let task = self.parse_one(line); map.insert(task.str_id(), task.id()); tasks.push(task);