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); 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()); + } 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. 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}; 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()) + } +} 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()