Skip to content

Commit 6cd9cdc

Browse files
committed
Add ContextProvider example
1 parent 249b45d commit 6cd9cdc

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

examples/dynamic/main.rs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use serde_json::Value;
2+
use std::{borrow::Cow, env};
3+
use tera::{Context, ContextProvider, Tera};
4+
5+
#[derive(Clone)]
6+
struct MyContext {
7+
upper_layer: Context, // for overrides
8+
}
9+
10+
impl MyContext {
11+
pub fn new() -> Self {
12+
Self { upper_layer: Context::new() }
13+
}
14+
}
15+
16+
impl ContextProvider for MyContext {
17+
fn try_insert<T: serde::Serialize + ?Sized, S: Into<String>>(
18+
&mut self,
19+
key: S,
20+
val: &T,
21+
) -> tera::Result<()> {
22+
self.upper_layer.try_insert(key, val)
23+
}
24+
25+
fn find_value(&self, key: &str) -> Option<Cow<Value>> {
26+
if let Some(val) = self.upper_layer.find_value(key) {
27+
return Some(val);
28+
}
29+
30+
env::var(key.to_uppercase()).map(Value::String).map(Cow::Owned).ok()
31+
}
32+
33+
fn find_value_by_dotted_pointer(&self, pointer: &str) -> Option<Cow<Value>> {
34+
env::var(pointer.to_uppercase().replace('.', "_"))
35+
.map(Value::String)
36+
.map(Cow::Owned)
37+
.ok()
38+
.or_else(|| self.upper_layer.find_value_by_dotted_pointer(pointer))
39+
}
40+
41+
fn into_json(self) -> Value {
42+
let Value::Object(map) = self.upper_layer.into_json() else { unreachable!() };
43+
Value::Object(map)
44+
}
45+
}
46+
47+
fn main() {
48+
env::set_var("SETTINGS_FOO", "bar");
49+
let ctx = MyContext::new();
50+
51+
let output = Tera::one_off("Hello {{ user }}! foo={{ settings.foo }}", &ctx, false).unwrap();
52+
53+
println!("{output}");
54+
}

0 commit comments

Comments
 (0)