aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Ryan McGrath <ryan@rymc.io>2018-07-21 18:27:47 +0000
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2018-07-22 14:47:29 +0100
commitc860bee5d5934fba6d57cbf815894a5cc8599ad9 (patch)
tree4dfc5efe28480e61a245db261daf0835e028602f
parentb231accdedf1c867f22c74d7588055c4e3576789 (diff)
downloadaskama-c860bee5d5934fba6d57cbf815894a5cc8599ad9.tar.gz
askama-c860bee5d5934fba6d57cbf815894a5cc8599ad9.tar.bz2
askama-c860bee5d5934fba6d57cbf815894a5cc8599ad9.zip
Add optional implementation for actix_web's Responder trait
-rw-r--r--askama/Cargo.toml3
-rw-r--r--askama/src/lib.rs28
-rw-r--r--askama_derive/Cargo.toml1
-rw-r--r--askama_derive/src/generator.rs23
-rw-r--r--askama_shared/Cargo.toml1
5 files changed, 56 insertions, 0 deletions
diff --git a/askama/Cargo.toml b/askama/Cargo.toml
index 638d43a..1e7f1ec 100644
--- a/askama/Cargo.toml
+++ b/askama/Cargo.toml
@@ -22,12 +22,15 @@ default = []
serde-json = ["askama_shared/serde-json"]
with-iron = ["iron", "askama_derive/iron"]
with-rocket = ["rocket", "askama_derive/rocket"]
+with-actix-web = ["actix-web", "askama_derive/actix-web", "mime_guess"]
[dependencies]
askama_derive = { path = "../askama_derive", version = "0.7.0" }
askama_shared = { version = "0.7.0", path = "../askama_shared" }
iron = { version = ">= 0.5, < 0.7", optional = true }
rocket = { version = "0.3", optional = true }
+actix-web = { version = "0.7", optional = true }
+mime_guess = { version = "2.0.0-alpha", optional = true }
[package.metadata.docs.rs]
features = [ "serde-json" ]
diff --git a/askama/src/lib.rs b/askama/src/lib.rs
index c31f341..77e49f2 100644
--- a/askama/src/lib.rs
+++ b/askama/src/lib.rs
@@ -306,6 +306,12 @@
//! unwraps any run-time errors from the template. If you have a better
//! suggestion, please [file an issue](https://github.com/djc/askama/issues/new).
//!
+//! ## Actix-web integration
+//!
+//! Enabling the `with-actix-web` feature appends an implementation of Actix-web's
+//! `Responder` trait for each template type. This makes it easy to return a value of
+//! that type in an Actix-web handler.
+//!
//! ## The `json` filter
//!
//! Enabling the `serde-json` filter will enable the use of the `json` filter.
@@ -366,6 +372,28 @@ pub mod rocket {
}
}
+#[cfg(feature = "with-actix-web")]
+pub mod actix_web {
+ extern crate actix_web;
+ extern crate mime_guess;
+
+ // actix_web technically has this as a pub fn in later versions, fs::file_extension_to_mime.
+ // Older versions that don't have it exposed are easier this way. If ext is empty or no
+ // associated type was found, then this returns `application/octet-stream`, in line with how
+ // actix_web handles it in newer releases.
+ pub use self::actix_web::{
+ error::ErrorInternalServerError, Error, HttpRequest, HttpResponse, Responder,
+ };
+ use self::mime_guess::get_mime_type;
+
+ pub fn respond(t: &super::Template, ext: &str) -> Result<HttpResponse, Error> {
+ let rsp = t.render()
+ .map_err(|_| ErrorInternalServerError("Template parsing error"))?;
+ let ctype = get_mime_type(ext).to_string();
+ Ok(HttpResponse::Ok().content_type(ctype.as_str()).body(rsp))
+ }
+}
+
fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<()> {
if dir.is_dir() {
for entry in fs::read_dir(dir)? {
diff --git a/askama_derive/Cargo.toml b/askama_derive/Cargo.toml
index 1834852..774fb51 100644
--- a/askama_derive/Cargo.toml
+++ b/askama_derive/Cargo.toml
@@ -15,6 +15,7 @@ proc-macro = true
default = []
iron = ["askama_shared/iron"]
rocket = ["askama_shared/rocket"]
+actix-web = ["askama_shared/actix-web"]
[dependencies]
askama_shared = { version = "0.7.0", path = "../askama_shared" }
diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs
index f586e1c..5af38c0 100644
--- a/askama_derive/src/generator.rs
+++ b/askama_derive/src/generator.rs
@@ -94,6 +94,9 @@ impl<'a> Generator<'a> {
if cfg!(feature = "rocket") {
self.impl_rocket_responder();
}
+ if cfg!(feature = "actix-web") {
+ self.impl_actix_web_responder();
+ }
self.buf
}
@@ -235,6 +238,26 @@ impl<'a> Generator<'a> {
self.writeln("}");
}
+ // Implement Actix-web's `Responder`.
+ fn impl_actix_web_responder(&mut self) {
+ self.write_header("::askama::actix_web::Responder", None);
+ self.writeln("type Item = ::askama::actix_web::HttpResponse;");
+ self.writeln("type Error = ::askama::actix_web::Error;");
+ self.writeln(
+ "fn respond_to<S>(self, _req: &::askama::actix_web::HttpRequest<S>) \
+ -> Result<Self::Item, Self::Error> {",
+ );
+
+ let ext = match self.input.path.extension() {
+ Some(s) => s.to_str().unwrap(),
+ None => "txt",
+ };
+ self.writeln(&format!("::askama::actix_web::respond(&self, {:?})", ext));
+
+ self.writeln("}");
+ self.writeln("}");
+ }
+
// Writes header for the `impl` for `TraitFromPathName` or `Template`
// for the given context struct.
fn write_header(&mut self, target: &str, params: Option<Vec<syn::GenericParam>>) {
diff --git a/askama_shared/Cargo.toml b/askama_shared/Cargo.toml
index cd052cf..5b93404 100644
--- a/askama_shared/Cargo.toml
+++ b/askama_shared/Cargo.toml
@@ -13,6 +13,7 @@ default = []
serde-json = ["serde_json"]
iron = []
rocket = []
+actix-web = []
[dependencies]
serde = "1.0"