pub mod ast;
pub mod errors;
pub mod lexer;
pub mod linker;
pub mod parser;
pub mod tokens;
use ast::ParseResult;
use errors::ParseError;
use linker::FileWorkflows;
pub fn parse_file(source: &str, filename: &str) -> ParseResult {
let lex_result = lexer::lex(source, filename);
if !lex_result.errors.is_empty() {
return ParseResult::Err {
errors: lex_result.errors,
};
}
parser::parse(lex_result.tokens, filename)
}
pub fn parse_file_path(path: &str) -> Result<ParseResult, std::io::Error> {
let source = std::fs::read_to_string(path)?;
let parse_result = parse_file(&source, path);
match parse_result {
ParseResult::Ok { workflows } => Ok(linker::link(vec![FileWorkflows {
filename: path.to_string(),
workflows,
}])),
err => Ok(err),
}
}
pub fn discover_and_parse(project_root: &str) -> Result<ParseResult, std::io::Error> {
let mut entries: Vec<String> = Vec::new();
let dir = std::fs::read_dir(project_root)?;
for entry in dir {
let entry = entry?;
let path = entry.path();
if path.is_file() {
if let Some(ext) = path.extension() {
if ext == "7" {
entries.push(path.to_string_lossy().to_string());
}
}
}
}
entries.sort();
if entries.is_empty() {
return Ok(ParseResult::Ok { workflows: vec![] });
}
let mut all_errors: Vec<ParseError> = Vec::new();
let mut file_workflows: Vec<FileWorkflows> = Vec::new();
let mut has_parse_errors = false;
for filepath in &entries {
let source = std::fs::read_to_string(filepath)?;
let result = parse_file(&source, filepath);
match result {
ParseResult::Ok { workflows } => {
file_workflows.push(FileWorkflows {
filename: filepath.clone(),
workflows,
});
}
ParseResult::Err { errors } => {
has_parse_errors = true;
all_errors.extend(errors);
}
}
}
if has_parse_errors {
return Ok(ParseResult::Err { errors: all_errors });
}
Ok(linker::link(file_workflows))
}