From ac60a18618b19ab60b9c550e2f9a38db853e23eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Madsen?= Date: Wed, 29 Jan 2020 09:32:39 +0100 Subject: [PATCH] Add support for warp --- .github/workflows/rust.yml | 14 ++++++++++++++ Cargo.toml | 2 ++ askama/Cargo.toml | 1 + askama/src/lib.rs | 7 +++++++ askama_derive/Cargo.toml | 1 + askama_derive/src/generator.rs | 17 +++++++++++++++++ askama_warp/Cargo.toml | 21 +++++++++++++++++++++ askama_warp/src/lib.rs | 19 +++++++++++++++++++ askama_warp/templates/hello.html | 1 + askama_warp/tests/warp.rs | 18 ++++++++++++++++++ testing/tests/simple.rs | 3 ++- 11 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 askama_warp/Cargo.toml create mode 100644 askama_warp/src/lib.rs create mode 100644 askama_warp/templates/hello.html create mode 100644 askama_warp/tests/warp.rs diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 3fc011c9f..887d11d27 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -89,6 +89,20 @@ jobs: cargo test --package askama_rocket --all-targets cargo clippy --package askama_rocket --all-targets -- -D warnings + Warp: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + override: true + components: clippy + - run: | + cargo test --package askama_warp --all-targets + cargo clippy --package askama_warp --all-targets -- -D warnings + Lint: runs-on: ubuntu-latest steps: diff --git a/Cargo.toml b/Cargo.toml index 6ff87a487..55a3dc850 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,10 @@ members = [ "askama_iron", "askama_rocket", "askama_shared", + "askama_warp", "testing", ] + default-members = [ "askama", "askama_derive", diff --git a/askama/Cargo.toml b/askama/Cargo.toml index a9749bae6..47da465f5 100644 --- a/askama/Cargo.toml +++ b/askama/Cargo.toml @@ -28,6 +28,7 @@ with-iron = ["askama_derive/iron"] with-rocket = ["askama_derive/rocket"] with-actix-web = ["askama_derive/actix-web"] with-gotham = ["askama_derive/gotham"] +with-warp = ["askama_derive/warp"] [dependencies] askama_derive = { version = "0.9.0", path = "../askama_derive" } diff --git a/askama/src/lib.rs b/askama/src/lib.rs index 4e4611b8d..1aa21bead 100644 --- a/askama/src/lib.rs +++ b/askama/src/lib.rs @@ -471,6 +471,13 @@ //! signature, with a status code of `500 Internal Server Error`, mime `*/*`, and an empty `Body`. //! This preserves the response chain if any custom error handling needs to occur. //! +//! ## Warp integration +//! +//! Enabling the `with-warp` feature appends an implementation of Warp's `Reply` +//! trait for each template type. This makes it simple to return a template from +//! a Warp filter. See [the example](https://github.com/djc/askama/blob/master/testing/tests/warp.rs) +//! from the Askama test suite for more on how to integrate. +//! //! ## The `json` filter //! //! Enabling the `serde-json` filter will enable the use of the `json` filter. diff --git a/askama_derive/Cargo.toml b/askama_derive/Cargo.toml index 93755f5b3..799f9899c 100644 --- a/askama_derive/Cargo.toml +++ b/askama_derive/Cargo.toml @@ -17,6 +17,7 @@ iron = [] rocket = [] actix-web = [] gotham = [] +warp = [] [dependencies] askama_shared = { version = "0.9", path = "../askama_shared" } diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index 9532057b4..ab1a012a5 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -97,6 +97,9 @@ impl<'a> Generator<'a> { if cfg!(feature = "gotham") { self.impl_gotham_into_response(&mut buf); } + if cfg!(feature = "warp") { + self.impl_warp_reply(&mut buf); + } buf.buf } @@ -272,6 +275,20 @@ impl<'a> Generator<'a> { buf.writeln("}"); } + fn impl_warp_reply(&mut self, buf: &mut Buffer) { + self.write_header(buf, "::askama_warp::warp::reply::Reply", None); + buf.writeln("fn into_response(self) -> ::askama_warp::warp::reply::Response {"); + let ext = self + .input + .path + .extension() + .and_then(|s| s.to_str()) + .unwrap_or("txt"); + buf.writeln(&format!("::askama_warp::reply(&self, {:?})", ext)); + buf.writeln("}"); + buf.writeln("}"); + } + // Writes header for the `impl` for `TraitFromPathName` or `Template` // for the given context struct. fn write_header( diff --git a/askama_warp/Cargo.toml b/askama_warp/Cargo.toml new file mode 100644 index 000000000..557ab46b1 --- /dev/null +++ b/askama_warp/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "askama_warp" +version = "0.9.0" +authors = ["Dirkjan Ochtman ", "Bjørn Madsen "] +description = "Warp integration for Askama templates" +documentation = "https://docs.rs/askama" +keywords = ["markup", "template", "jinja2", "html"] +categories = ["template-engine"] +homepage = "https://github.com/djc/askama" +repository = "https://github.com/djc/askama" +license = "MIT OR Apache-2.0" +workspace = ".." +edition = "2018" + +[dependencies] +askama = { version = "0.9.0", path = "../askama", features = ["with-warp", "mime", "mime_guess"] } +warp = "0.2" + +[dev-dependencies] +tokio-test = "0.2" +tokio = { version = "0.2", features = ["macros"] } diff --git a/askama_warp/src/lib.rs b/askama_warp/src/lib.rs new file mode 100644 index 000000000..1ea007689 --- /dev/null +++ b/askama_warp/src/lib.rs @@ -0,0 +1,19 @@ +pub use askama::*; +pub use warp; + +use warp::http::{self, header, StatusCode}; +use warp::hyper::Body; +use warp::reply::Response; + +pub fn reply(t: &T, ext: &str) -> Response { + match t.render() { + Ok(body) => http::Response::builder() + .status(StatusCode::OK) + .header(header::CONTENT_TYPE, mime::extension_to_mime_type(ext).to_string()) + .body(body.into()), + Err(_) => http::Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::empty()), + } + .unwrap() +} diff --git a/askama_warp/templates/hello.html b/askama_warp/templates/hello.html new file mode 100644 index 000000000..8149be7a6 --- /dev/null +++ b/askama_warp/templates/hello.html @@ -0,0 +1 @@ +Hello, {{ name }}! diff --git a/askama_warp/tests/warp.rs b/askama_warp/tests/warp.rs new file mode 100644 index 000000000..69a5f2344 --- /dev/null +++ b/askama_warp/tests/warp.rs @@ -0,0 +1,18 @@ +use askama::Template; +use warp::Filter; + +#[derive(Template)] +#[template(path = "hello.html")] +struct HelloTemplate<'a> { + name: &'a str, +} + +#[tokio::test] +async fn test_warp() { + let filter = warp::get().map(|| HelloTemplate { name: "world" }); + + let res = warp::test::request().reply(&filter).await; + + assert_eq!(res.status(), 200); + assert_eq!(res.body(), "Hello, world!"); +} diff --git a/testing/tests/simple.rs b/testing/tests/simple.rs index a075d26e6..354459954 100644 --- a/testing/tests/simple.rs +++ b/testing/tests/simple.rs @@ -203,8 +203,9 @@ fn test_option() { #[derive(Template)] #[template(path = "generics.html")] -struct GenericsTemplate +struct GenericsTemplate where + T: std::fmt::Display, U: std::fmt::Display, { t: T,