ips/specfile/src/macros.rs

103 lines
3.9 KiB
Rust
Raw Normal View History

2025-07-26 12:54:01 +02:00
use anyhow::Result;
use pest::Parser;
use pest_derive::Parser;
use std::collections::HashMap;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum MacroParserError {
#[error("macro does not exist: {macro_name}")]
2025-07-26 12:54:01 +02:00
DoesNotExist { macro_name: String },
}
#[derive(Parser)]
#[grammar = "macro.pest"]
struct InternalMacroParser;
#[derive(Default, Debug)]
pub struct MacroParser {
2025-07-26 12:54:01 +02:00
pub macros: HashMap<String, String>,
}
#[derive(Default, Debug)]
pub struct Macro {
pub name: String,
2025-07-26 12:54:01 +02:00
pub parameters: Vec<String>,
}
impl MacroParser {
2025-07-26 12:54:01 +02:00
pub fn parse(&self, raw_string: String) -> Result<String> {
let mut return_string = String::new();
for (i, line) in raw_string.lines().enumerate() {
let mut replaced_line = String::new();
let pairs = InternalMacroParser::parse(Rule::file, line)?;
for pair in pairs {
for test_pair in pair.into_inner() {
match test_pair.as_rule() {
Rule::text_with_macros => {
for inner in test_pair.into_inner() {
match inner.as_rule() {
Rule::spec_macro => {
for macro_pair in inner.clone().into_inner() {
match macro_pair.as_rule() {
Rule::macro_name => {
replaced_line +=
self.get_variable(macro_pair.as_str())?;
}
Rule::macro_parameter => {
println!(
"macro parameter: {}",
macro_pair.as_str()
)
}
_ => panic!(
"Unexpected macro match please update the code together with the peg grammar: {:?}",
macro_pair.as_rule()
),
}
}
}
_ => panic!(
"Unexpected inner match please update the code together with the peg grammar: {:?}",
inner.as_rule()
),
}
}
}
Rule::EOI => (),
Rule::text => {
replaced_line += test_pair.as_str();
replaced_line += " ";
}
_ => panic!(
"Unexpected match please update the code together with the peg grammar: {:?}",
test_pair.as_rule()
),
}
}
}
replaced_line = replaced_line.trim_end().to_owned();
if i == 0 {
return_string += &replaced_line;
} else {
return_string += "\n";
return_string += &replaced_line;
}
}
Ok(return_string)
}
fn get_variable(&self, macro_name: &str) -> Result<&str> {
if self.macros.contains_key(macro_name) {
2025-07-26 12:54:01 +02:00
return Ok(self.macros[macro_name].as_str());
}
2025-07-26 12:54:01 +02:00
Err(MacroParserError::DoesNotExist {
macro_name: macro_name.into(),
})?
}
}