Skip to content

Commit

Permalink
Merge pull request #48 from kdesjard/yaml_read_from_str
Browse files Browse the repository at this point in the history
  • Loading branch information
genedna authored Dec 11, 2023
2 parents b5f467a + 0590f35 commit a7ed957
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 17 deletions.
17 changes: 12 additions & 5 deletions examples/custom_parser_and_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,9 @@ impl Display for MyTask {
struct ConfigParser;

impl ConfigParser {
fn load_file(&self, file: &str) -> Result<Vec<String>, ParseError> {
fn load_file(&self, file: &str) -> Result<String, ParseError> {
let contents = fs::read_to_string(file).map_err(|e| e.to_string())?;
let lines: Vec<String> = contents.lines().map(|line| line.to_string()).collect();
Ok(lines)
Ok(contents)
}

fn parse_one(&self, item: String) -> MyTask {
Expand All @@ -109,12 +108,20 @@ impl Parser for ConfigParser {
fn parse_tasks(
&self,
file: &str,
_specific_actions: HashMap<String, Action>,
specific_actions: HashMap<String, Action>,
) -> Result<Vec<Box<dyn Task>>, 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<String, Action>,
) -> Result<Vec<Box<dyn Task>>, ParseError> {
let lines: Vec<String> = 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);
Expand Down
6 changes: 6 additions & 0 deletions examples/yaml_dag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());

}
35 changes: 35 additions & 0 deletions src/engine/dag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, Action>,
) -> Result<Dag, DagError> {
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,
Expand All @@ -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<dyn Parser>,
specific_actions: HashMap<String, Action>,
) -> Result<Dag, DagError> {
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(
Expand All @@ -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<dyn Parser>,
specific_actions: HashMap<String, Action>,
) -> Result<Dag, DagError> {
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.
Expand Down
10 changes: 10 additions & 0 deletions src/utils/file.rs
Original file line number Diff line number Diff line change
@@ -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<String, Error> {
let mut content = String::new();
let mut fh = File::open(file)?;
fh.read_to_string(&mut content)?;
Ok(content)
}
1 change: 1 addition & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
mod env;
mod parser;
pub mod file;

pub use self::env::EnvVar;
pub use self::parser::{ParseError, Parser};
12 changes: 12 additions & 0 deletions src/utils/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ pub trait Parser {
file: &str,
specific_actions: HashMap<String, Action>,
) -> Result<Vec<Box<dyn Task>>, ParseError>;

fn parse_tasks_from_str(
&self,
content: &str,
specific_actions: HashMap<String, Action>,
) -> Result<Vec<Box<dyn Task>>, ParseError>;
}

/// Errors that may occur during configuration file parsing.
Expand All @@ -40,3 +46,9 @@ impl From<String> for ParseError {
ParseError(value)
}
}

impl From<std::io::Error> for ParseError {
fn from(value: std::io::Error) -> Self {
ParseError(value.to_string())
}
}
24 changes: 12 additions & 12 deletions src/yaml/yaml_parser.rs
Original file line number Diff line number Diff line change
@@ -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<String, ParseError> {
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:
///
Expand Down Expand Up @@ -63,15 +56,22 @@ impl Parser for YamlParser {
fn parse_tasks(
&self,
file: &str,
specific_actions: HashMap<String, Action>,
) -> Result<Vec<Box<dyn Task>>, 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<String, Action>,
) -> Result<Vec<Box<dyn Task>>, 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()
Expand Down

0 comments on commit a7ed957

Please sign in to comment.