diff options
Diffstat (limited to '')
-rw-r--r-- | askama/Cargo.toml | 3 | ||||
-rw-r--r-- | askama/src/lib.rs | 28 | ||||
-rw-r--r-- | askama_derive/Cargo.toml | 1 | ||||
-rw-r--r-- | askama_derive/src/generator.rs | 23 | ||||
-rw-r--r-- | askama_shared/Cargo.toml | 1 |
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" |