1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
use crate::{Assigns, HandlebarsHandler};
use serde::Serialize;
use serde_json::json;
use std::borrow::Cow;
use trillium::Conn;
/**
Extension trait that provides handlebar rendering capabilities to
[`trillium::Conn`]s.
*/
pub trait HandlebarsConnExt {
/**
Registers an "assigns" value on this Conn for use in a template.
See example usage at [`Handlebars::new`](crate::Handlebars::new)
*/
fn assign(self, key: impl Into<Cow<'static, str>>, data: impl Serialize) -> Self;
/**
renders a registered template by name with the provided data as
assigns. note that this does not use any data accumulated by
[`HandlebarsConnExt::assign`]
```
use trillium_handlebars::{HandlebarsHandler, Handlebars, HandlebarsConnExt};
# fn main() -> Result<(), Box<dyn std::error::Error>> {
#[derive(serde::Serialize)]
struct User { name: &'static str };
let mut handlebars = Handlebars::new();
handlebars.register_template_string("greet-user", "Hello {{name}}")?;
let handler = (
HandlebarsHandler::new(handlebars),
|mut conn: trillium::Conn| async move {
conn.render_with("greet-user", &User { name: "handlebars" })
}
);
use trillium_testing::prelude::*;
assert_ok!(get("/").on(&handler), "Hello handlebars");
# Ok(()) }
```
*/
fn render_with(self, template: &str, data: &impl Serialize) -> Self;
/**
renders a registered template, passing any accumulated assigns to
the template. See example at [`Handlebars::new`](crate::Handlebars::new)
*/
fn render(self, template: &str) -> Self;
/// retrieves a reference to any accumulated assigns on this conn
fn assigns(&self) -> Option<&Assigns>;
/**
retrieves a mutable reference to any accumulated assigns on this
conn
*/
fn assigns_mut(&mut self) -> &mut Assigns;
}
impl HandlebarsConnExt for Conn {
fn render_with(self, template: &str, data: &impl Serialize) -> Self {
let handlebars: &HandlebarsHandler = self
.state()
.expect("HandlebarsConnExt::render called without running the handler first");
match handlebars.render(template, data) {
Ok(string) => self.ok(string),
Err(b) => self.with_status(500).with_body(b.to_string()),
}
}
fn assign(mut self, key: impl Into<Cow<'static, str>>, data: impl Serialize) -> Self {
self.assigns_mut().insert(
key.into(),
serde_json::to_value(data).expect("could not serialize assigns"),
);
self
}
fn render(self, template: &str) -> Self {
let handlebars: &HandlebarsHandler = self
.state()
.expect("HandlebarsConnExt::render called without running the handler first");
let string = if let Some(assigns) = self.assigns() {
handlebars.render(template, assigns)
} else {
handlebars.render(template, &json!({}))
};
match string {
Ok(string) => self.ok(string),
Err(b) => self.with_status(500).with_body(b.to_string()),
}
}
fn assigns(&self) -> Option<&Assigns> {
self.state()
}
fn assigns_mut(&mut self) -> &mut Assigns {
self.mut_state_or_insert_with(Assigns::default)
}
}