rust
```cargo
[dependencies]
minijinja = "1.0.12"
```
use minijinja::value::{Object, Value};
use minijinja::{context, Environment, Error};
use std::fmt::Display;
use std::sync::Mutex;
use std::collections::BTreeMap;
fn main() {
let cache = Mutex::new(BTreeMap::new());
let mut env = Environment::new();
env.add_template("cache_test", "{{ widget.ping() }} {{ widget.ping() }}")
.unwrap();
let tmpl = env.get_template("cache_test").unwrap();
let widget = Widget { cache };
println!(
"{}",
tmpl.render(context!(widget => Value::from_object(widget)))
.unwrap()
);
}
#[derive(Debug)]
pub struct Widget {
pub cache : Mutex<BTreeMap<String, u8>>,
}
impl Widget {
pub fn new(cache: Mutex<BTreeMap<String, u8>>) -> Widget {
Widget { cache }
}
pub fn ping(&self) -> u8 {
let mut cache = self.cache.lock().unwrap();
match cache.get("counter") {
Some(value) => *value,
None => {
cache.insert("counter".to_string(), 1);
0
}
}
}
}
impl Object for Widget {
fn call_method(
&self,
_state: &minijinja::State,
name: &str,
_args: &[Value],
) -> Result<Value, Error> {
match name {
"ping" => Ok(Value::from(self.ping())),
_ => Ok(Value::from("")),
}
}
}
impl Display for Widget {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "this is required from minijinja but rarely used")
}
}
results start
rust
pub fn page_title(&self, id: &str) -> Option<String> {
let mut cache = self.cache.lock().unwrap();
let page_titles = cache.get_mut("page_title").unwrap();
match page_titles.get(id) {
Some(title) => title.clone(),
None => {
let title = match self.pages.get(id) {
Some(page) => get_title_section_title(&page.ast),
None => None,
};
page_titles.insert(id.to_string(), title.clone());
title
}
}
}
This still needs a write up. Here's the code in the mean time