Call A Function On An Object From A minijinja Template
Look At This And Compare It With The Old Notes
You can refine this so it's not a point and just use something else without needing three variable examples.
```cargo
[dependencies]
minijinja = "2.7.0"
```
use minijinja::value::Enumerator;
use minijinja::value::Object;
use minijinja::{context, Environment, Error, Value};
use std::sync::Arc;
#[derive(Debug)]
struct Point(f32, f32, f32);
impl Point {
pub fn ping(&self, args: &[Value]) -> Result<Value, Error> {
Ok(Value::from(args[0].clone()))
}
}
impl Object for Point {
fn call_method(
self: &Arc<Point>,
_state: &minijinja::State,
name: &str,
args: &[Value],
) -> Result<Value, Error> {
match name {
"ping" => self.ping(args),
_ => Ok(Value::from("")),
}
}
fn get_value(self: &Arc<Self>, key: &Value) -> Option<Value> {
match key.as_str()? {
"x" => Some(Value::from(self.0)),
"y" => Some(Value::from(self.1)),
"z" => Some(Value::from(self.2)),
_ => None,
}
}
fn enumerate(self: &Arc<Self>) -> Enumerator {
Enumerator::Str(&["x", "y", "z"])
}
}
fn main() {
let value = Value::from_object(Point(1.0, 2.5, 3.0));
let mut env = Environment::new();
env.add_template("basic", "{{ value.ping('foxtrot') }}").unwrap();
let skeleton = env.get_template("basic").unwrap();
let output = skeleton
.render(context!(
value => value
))
.unwrap();
dbg!(output);
}
Output:
[/Users/alan/.cargo/target/55/19854259915251/_active_nvim_run:56:5] output = "foxtrotx"
Old Notes
MiniJinja 2.x
```cargo
[dependencies]
minijinja = "2.0.1"
```
use minijinja::value::{Object, Value};
use minijinja::{context, Environment, Error};
use std::fmt::Display;
use std::sync::Arc;
fn main() {
let mut env = Environment::new();
env.add_template("hello", "{{ alfa_value.ping() }}")
.unwrap();
let tmpl = env.get_template("hello").unwrap();
let alfa = Alfa {};
let alfa_value = Value::from_object(alfa);
println!(
"{}",
tmpl.render(context!(alfa_value => alfa_value)).unwrap()
);
}
#[derive(Debug)]
pub struct Alfa {}
impl Object for Alfa {
fn call_method(
self: &Arc<Alfa>,
_state: &minijinja::State,
name: &str,
_args: &[Value],
) -> Result<Value, Error> {
match name {
// NOTE: May need to do:
// Value::from_serializable.
// TODO: Look into that
"ping" => Ok(Value::from(self.ping())),
_ => {
// TODO: make this an error possibly
Ok(Value::from(""))
}
}
}
}
impl Display for Alfa {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "THIS IS ALFA DISPLAY DEFAULT FORMAT")
}
}
impl Alfa {
fn ping(&self) -> String {
"One ping only".to_string()
}
}
Output:
One ping only
MiniJinja 1.x
[package]
name = "minijinji_object_method_call"
version = "0.1.0"
edition = "2021"
[dependencies]
minijinja = "1.0.7"
src/main.rs
use minijinja::value::{Object, Value};
use minijinja::{context, Environment, Error};
use std::fmt::Display;
fn main() {
let mut env = Environment::new();
env.add_template("hello", "{{ alfa_value.ping() }}")
.unwrap();
let tmpl = env.get_template("hello").unwrap();
let alfa = Alfa {};
let alfa_value = Value::from_object(alfa);
println!(
"{}",
tmpl.render(context!(alfa_value => alfa_value)).unwrap()
);
}
#[derive(Debug)]
pub struct Alfa {}
impl Object for Alfa {
fn call_method(
&self,
_state: &minijinja::State,
name: &str,
_args: &[Value],
) -> Result<Value, Error> {
match name {
// NOTE: May need to do:
// Value::from_serializable.
// TODO: Look into that
"ping" => Ok(Value::from(self.ping())),
_ => {
// TODO: make this an error possibly
Ok(Value::from(""))
}
}
}
}
impl Display for Alfa {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "THIS IS ALFA DISPLAY DEFAULT FORMAT")
}
}
impl Alfa {
fn ping(&self) -> String {
"One ping only".to_string()
}
}
TODO
☐
Switch to using Value::from_serializable as well which can be used for vecs of objects
☐
Update this test with args
passing from call method to ping
via args[0]
-- end of line --