use chrono::Datelike as _;
use chrono::Timelike as _;
use regex::Regex;
use serde_json::Value;
use super::data::NdtData;
fn placeholder_re() -> Regex {
Regex::new(r"\{\{([a-zA-Z0-9_\.]+)\}\}").expect("static regex")
}
pub fn resolve_string(text: &str, data: &NdtData) -> String {
let re = placeholder_re();
re.replace_all(text, |caps: ®ex::Captures| {
let key = &caps[1];
data.get_string(key).unwrap_or_else(|| caps[0].to_string())
})
.into_owned()
}
pub fn resolve_value(text: &str, data: &NdtData) -> Option<Value> {
let re = placeholder_re();
let trimmed = text.trim();
let caps = re.captures(trimmed)?;
if caps.get(0)?.as_str() != trimmed {
return None;
}
data.get(&caps[1]).cloned()
}
pub struct RuntimeContext {
pub page_number: u32,
pub total_pages: u32,
pub today: String,
pub now: String,
}
impl RuntimeContext {
pub fn new(page_number: u32, total_pages: u32) -> Self {
let dt = chrono::Local::now();
const MONTHS: [&str; 12] = [
"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho",
"Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro",
];
let month_name = MONTHS[(dt.month0()) as usize];
let today = format!("{} de {} de {}", dt.day(), month_name, dt.year());
let now = format!(
"{:02}/{:02}/{} {:02}:{:02}",
dt.day(), dt.month(), dt.year(), dt.hour(), dt.minute()
);
Self { page_number, total_pages, today, now }
}
}
pub fn resolve_runtime_fields(text: &str, ctx: &RuntimeContext) -> String {
text.replace("{{page}}", &ctx.page_number.to_string())
.replace("{{total_pages}}", &ctx.total_pages.to_string())
.replace("{{today}}", &ctx.today)
.replace("{{now}}", &ctx.now)
}