use std::collections::HashMap;
use pest::Parser;
use pest_derive::Parser;
#[derive(Parser)]
#[grammar = "src/parser/context.pest"]
struct VarPlaceholderParser;
pub fn inject_from_prompt(input: &str) -> String {
let mut output = String::new();
let mut pairs = VarPlaceholderParser::parse(Rule::text, input).unwrap();
let pair = pairs.next().unwrap();
for inner_pair in pair.into_inner() {
match inner_pair.as_rule() {
Rule::word => {
output.push_str(inner_pair.as_str());
}
Rule::input => {
let prompt = format!("Provide a value for \"{}\"", inner_pair.as_str());
let input: String = dialoguer::Input::new()
.with_prompt(prompt)
.interact()
.unwrap();
output.push_str(input.as_str());
}
Rule::var => {
output.push_str(format!("{{{{{}}}}}", inner_pair.as_str()).as_str());
}
_ => {
unreachable!("unexpected rule: {:?}", inner_pair.as_rule());
}
}
}
output
}
pub fn inject_from_variable(input: &str, context: &HashMap<String, String>) -> String {
let mut output = String::new();
let mut pairs = VarPlaceholderParser::parse(Rule::text, input).unwrap();
let pair = pairs.next().unwrap();
for inner_pair in pair.into_inner() {
match inner_pair.as_rule() {
Rule::word => {
output.push_str(inner_pair.as_str());
}
Rule::var => {
let key = inner_pair.as_str().to_string();
let value = context
.get(&key)
.expect(&format!("No value found for variable: {}", key));
output.push_str(value);
}
Rule::input => {
output.push_str(format!("[[{}]]", inner_pair.as_str()).as_str());
}
_ => {
unreachable!("unexpected rule: {:?}", inner_pair.as_rule());
}
}
}
output
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn should_replace_variables() {
let input = "this is a test with a {{variable}}";
let mut context = HashMap::new();
context.insert("variable".to_string(), "value".to_string());
let output = inject_from_variable(input, &context);
assert_eq!(output, "this is a test with a value");
}
}