use std::path::PathBuf;
use pest::Parser;
use pest_derive::Parser;
#[derive(Parser)]
#[grammar = "src/parser/preprocessor.pest"]
struct PreprocessorParser;
pub fn preprocess(input: &str, working_dir: PathBuf) -> Result<String, pest::error::Error<Rule>> {
let mut lines: Vec<String> = vec![];
let mut pairs = PreprocessorParser::parse(Rule::body, input)?;
let pair = pairs.next().unwrap();
for inner_pair in pair.into_inner() {
match inner_pair.as_rule() {
Rule::line => {
lines.push(inner_pair.as_str().trim().to_string());
}
Rule::import_target => {
let arg = inner_pair.as_str().trim();
lines.push(resolve_import(arg, &working_dir)?);
}
_ => {
unreachable!("unexpected rule: {:?}", inner_pair.as_rule());
}
}
}
Ok(lines.join("\n"))
}
fn resolve_import(path: &str, working_dir: &PathBuf) -> Result<String, pest::error::Error<Rule>> {
let path = working_dir.join(path);
let path = PathBuf::from(path);
let file_content = std::fs::read_to_string(path).expect("failed to read import");
preprocess(&file_content, working_dir.clone())
}