Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
wrapperup committed Mar 15, 2024
2 parents ed92223 + 353304c commit 2b67283
Show file tree
Hide file tree
Showing 90 changed files with 3,445 additions and 1,277 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/rust.yml
Expand Up @@ -32,9 +32,8 @@ jobs:
strategy:
matrix:
package: [
askama, askama_actix, askama_axum, askama_derive, askama_escape, askama_gotham,
askama_hyper, askama_mendes, askama_parser, askama_rocket, askama_tide, askama_warp,
testing,
askama, askama_actix, askama_axum, askama_derive, askama_escape,
askama_parser, askama_rocket, askama_warp, testing,
]
runs-on: ubuntu-latest
steps:
Expand Down
4 changes: 0 additions & 4 deletions Cargo.toml
Expand Up @@ -3,15 +3,11 @@ members = [
"askama",
"askama_actix",
"askama_axum",
"askama_gotham",
"askama_derive",
"askama_escape",
"askama_mendes",
"askama_parser",
"askama_rocket",
"askama_tide",
"askama_warp",
"askama_hyper",
"testing",
]
resolver = "2"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -26,7 +26,7 @@ in a for-profit context, please consider supporting my open source work on
* Construct templates using a familiar, easy-to-use syntax
* Benefit from the safety provided by Rust's type system
* Template code is compiled into your crate for [optimal performance][benchmarks]
* Optional built-in support for Actix, Axum, Gotham, Mendes, Rocket, tide, and warp web frameworks
* Optional built-in support for Actix, Axum, Rocket, and warp web frameworks
* Debugging features to assist you in template development
* Templates must be valid UTF-8 and produce UTF-8 when rendered
* IDE support available in [JetBrains products](https://plugins.jetbrains.com/plugin/16591-askama-template-support)
Expand Down
10 changes: 3 additions & 7 deletions askama/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "askama"
version = "0.12.1"
version = "0.13.0"
description = "Type-safe, compiled Jinja-like templates for Rust"
documentation = "https://docs.rs/askama"
keywords = ["markup", "template", "jinja2", "html"]
Expand All @@ -27,21 +27,17 @@ serde-yaml = ["askama_derive/serde-yaml", "serde", "serde_yaml"]
urlencode = ["askama_derive/urlencode", "percent-encoding"]
with-actix-web = ["askama_derive/with-actix-web"]
with-axum = ["askama_derive/with-axum"]
with-gotham = ["askama_derive/with-gotham"]
with-hyper = ["askama_derive/with-hyper"]
with-mendes = ["askama_derive/with-mendes"]
with-rocket = ["askama_derive/with-rocket"]
with-tide = ["askama_derive/with-tide"]
with-warp = ["askama_derive/with-warp"]

# deprecated
mime = []
mime_guess = []

[dependencies]
askama_derive = { version = "0.12.0", path = "../askama_derive" }
askama_derive = { version = "0.13", path = "../askama_derive" }
askama_escape = { version = "0.10.3", path = "../askama_escape" }
comrak = { version = "0.18", optional = true, default-features = false }
comrak = { version = "0.21", optional = true, default-features = false }
dep_humansize = { package = "humansize", version = "2", optional = true }
dep_num_traits = { package = "num-traits", version = "0.2.6", optional = true }
percent-encoding = { version = "2.1.0", optional = true }
Expand Down
1 change: 1 addition & 0 deletions askama/src/error.rs
Expand Up @@ -90,6 +90,7 @@ impl From<::serde_yaml::Error> for Error {
mod tests {
use super::Error;

#[allow(dead_code)]
trait AssertSendSyncStatic: Send + Sync + 'static {}
impl AssertSendSyncStatic for Error {}
}
51 changes: 11 additions & 40 deletions askama/src/filters/mod.rs
Expand Up @@ -345,51 +345,22 @@ pub fn wordcount<T: fmt::Display>(s: T) -> Result<usize> {
pub fn markdown<E, S>(
e: E,
s: S,
options: Option<&comrak::ComrakOptions>,
options: Option<&comrak::Options>,
) -> Result<MarkupDisplay<E, String>>
where
E: Escaper,
S: AsRef<str>,
{
use comrak::{
markdown_to_html, ComrakExtensionOptions, ComrakOptions, ComrakParseOptions,
ComrakRenderOptions, ListStyleType,
};

const DEFAULT_OPTIONS: ComrakOptions = ComrakOptions {
extension: ComrakExtensionOptions {
strikethrough: true,
tagfilter: true,
table: true,
autolink: true,
// default:
tasklist: false,
superscript: false,
header_ids: None,
footnotes: false,
description_lists: false,
front_matter_delimiter: None,
},
parse: ComrakParseOptions {
// default:
smart: false,
default_info_string: None,
relaxed_tasklist_matching: false,
},
render: ComrakRenderOptions {
escape: true,
// default:
hardbreaks: false,
github_pre_lang: false,
full_info_string: false,
width: 0,
unsafe_: false,
list_style: ListStyleType::Dash,
sourcepos: false,
},
};

let s = markdown_to_html(s.as_ref(), options.unwrap_or(&DEFAULT_OPTIONS));
use comrak::{markdown_to_html, Options};

let mut defaults = Options::default();
defaults.extension.strikethrough = true;
defaults.extension.tagfilter = true;
defaults.extension.table = true;
defaults.extension.autolink = true;
defaults.render.escape = true;

let s = markdown_to_html(s.as_ref(), options.unwrap_or(&defaults));
Ok(MarkupDisplay::new_safe(s, e))
}

Expand Down
32 changes: 23 additions & 9 deletions askama/src/lib.rs
Expand Up @@ -115,6 +115,29 @@ pub trait Template: fmt::Display {
const MIME_TYPE: &'static str;
}

impl<T: Template + ?Sized> Template for &T {
#[inline]
fn render_into(&self, writer: &mut (impl std::fmt::Write + ?Sized)) -> Result<()> {
T::render_into(self, writer)
}

#[inline]
fn render(&self) -> Result<String> {
T::render(self)
}

#[inline]
fn write_into(&self, writer: &mut (impl std::io::Write + ?Sized)) -> std::io::Result<()> {
T::write_into(self, writer)
}

const EXTENSION: Option<&'static str> = T::EXTENSION;

const SIZE_HINT: usize = T::SIZE_HINT;

const MIME_TYPE: &'static str = T::MIME_TYPE;
}

/// Object-safe wrapper trait around [`Template`] implementers
///
/// This trades reduced performance (mostly due to writing into `dyn Write`) for object safety.
Expand Down Expand Up @@ -171,15 +194,6 @@ impl fmt::Display for dyn DynTemplate {
}
}

/// Old build script helper to rebuild crates if contained templates have changed
///
/// This function is now deprecated and does nothing.
#[deprecated(
since = "0.8.1",
note = "file-level dependency tracking is handled automatically without build script"
)]
pub fn rerun_if_templates_changed() {}

#[cfg(test)]
mod tests {
use std::fmt;
Expand Down
4 changes: 2 additions & 2 deletions askama_actix/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "askama_actix"
version = "0.14.0"
version = "0.15.0"
description = "Actix-Web integration for Askama templates"
documentation = "https://docs.rs/askama"
keywords = ["markup", "template", "jinja2", "html"]
Expand All @@ -15,7 +15,7 @@ rust-version = "1.65"

[dependencies]
actix-web = { version = "4", default-features = false }
askama = { version = "0.12", path = "../askama", default-features = false, features = ["with-actix-web"] }
askama = { version = "0.13", path = "../askama", default-features = false, features = ["with-actix-web"] }

[dev-dependencies]
actix-rt = { version = "2", default-features = false }
Expand Down
32 changes: 17 additions & 15 deletions askama_actix/src/lib.rs
Expand Up @@ -4,13 +4,30 @@

use std::fmt;

#[doc(no_inline)]
pub use actix_web;
use actix_web::body::BoxBody;
use actix_web::http::header::HeaderValue;
use actix_web::http::StatusCode;
use actix_web::{HttpResponse, HttpResponseBuilder, ResponseError};
#[doc(no_inline)]
pub use askama::*;

/// Render a [`Template`] into a [`HttpResponse`], or render an error page.
pub fn into_response<T: ?Sized + askama::Template>(tmpl: &T) -> HttpResponse<BoxBody> {
try_into_response(tmpl).unwrap_or_else(|err| HttpResponse::from_error(ActixError(err)))
}

/// Try to render a [`Template`] into a [`HttpResponse`].
pub fn try_into_response<T: ?Sized + askama::Template>(
tmpl: &T,
) -> Result<HttpResponse<BoxBody>, Error> {
let value = tmpl.render()?;
Ok(HttpResponseBuilder::new(StatusCode::OK)
.content_type(HeaderValue::from_static(T::MIME_TYPE))
.body(value))
}

/// Newtype to let askama::Error implement actix_web::ResponseError.
struct ActixError(Error);

Expand All @@ -29,18 +46,3 @@ impl fmt::Display for ActixError {
}

impl ResponseError for ActixError {}

pub trait TemplateToResponse {
fn to_response(&self) -> HttpResponse<BoxBody>;
}

impl<T: askama::Template> TemplateToResponse for T {
fn to_response(&self) -> HttpResponse<BoxBody> {
match self.render() {
Ok(buffer) => HttpResponseBuilder::new(StatusCode::OK)
.content_type(HeaderValue::from_static(T::MIME_TYPE))
.body(buffer),
Err(err) => HttpResponse::from_error(ActixError(err)),
}
}
}
23 changes: 1 addition & 22 deletions askama_actix/tests/basic.rs
@@ -1,6 +1,6 @@
use actix_web::http::header::CONTENT_TYPE;
use actix_web::web;
use askama_actix::{Template, TemplateToResponse};
use askama_actix::Template;
use bytes::Bytes;

#[derive(Template)]
Expand All @@ -27,24 +27,3 @@ async fn test_actix_web() {
let bytes = response.body().await.unwrap();
assert_eq!(bytes, Bytes::from_static("Hello, world!".as_ref()));
}

#[actix_rt::test]
async fn test_actix_web_responder() {
let srv = actix_test::start(|| {
actix_web::App::new().service(web::resource("/").to(|| async {
let name = "world".to_owned();
HelloTemplate { name: &name }.to_response()
}))
});

let request = srv.get("/");
let mut response = request.send().await.unwrap();
assert!(response.status().is_success());
assert_eq!(
response.headers().get(CONTENT_TYPE).unwrap(),
"text/html; charset=utf-8"
);

let bytes = response.body().await.unwrap();
assert_eq!(bytes, Bytes::from_static("Hello, world!".as_ref()));
}
13 changes: 7 additions & 6 deletions askama_axum/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "askama_axum"
version = "0.3.0"
version = "0.5.0"
edition = "2021"
rust-version = "1.65"
description = "Axum integration for Askama templates"
Expand All @@ -14,13 +14,14 @@ workspace = ".."
readme = "README.md"

[dependencies]
askama = { version = "0.12", path = "../askama", default-features = false, features = ["with-axum", "mime", "mime_guess"] }
axum-core = "0.3"
http = "0.2"
askama = { version = "0.13", path = "../askama", default-features = false, features = ["with-axum", "mime", "mime_guess"] }
axum-core = "0.4"
http = "1.0"

[dev-dependencies]
axum = { version = "0.6", default-features = false }
hyper = { version = "0.14", features = ["full"] }
axum = { version = "0.7", default-features = false }
http-body-util = "0.1"
hyper = { version = "1.0", features = ["full"] }
tokio = { version = "1.0", features = ["full"] }
tower = { version = "0.4", features = ["util"] }

Expand Down
33 changes: 20 additions & 13 deletions askama_axum/src/lib.rs
Expand Up @@ -2,20 +2,27 @@
#![deny(elided_lifetimes_in_paths)]
#![deny(unreachable_pub)]

#[doc(no_inline)]
pub use askama::*;
pub use axum_core::response::{IntoResponse, Response};
use http::StatusCode;
#[doc(no_inline)]
pub use axum_core;
use axum_core::response::{IntoResponse, Response};

pub fn into_response<T: Template>(t: &T) -> Response {
match t.render() {
Ok(body) => {
let headers = [(
http::header::CONTENT_TYPE,
http::HeaderValue::from_static(T::MIME_TYPE),
)];
/// Render a [`Template`] into a [`Response`], or render an error page.
pub fn into_response<T: ?Sized + askama::Template>(tmpl: &T) -> Response {
try_into_response(tmpl)
.map_err(|err| axum_core::response::ErrorResponse::from(err.to_string()))
.into_response()
}

(headers, body).into_response()
}
Err(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
}
/// Try to render a [`Template`] into a [`Response`].
pub fn try_into_response<T: ?Sized + askama::Template>(tmpl: &T) -> Result<Response, Error> {
let value = tmpl.render()?.into();
Response::builder()
.header(
http::header::CONTENT_TYPE,
http::header::HeaderValue::from_static(T::MIME_TYPE),
)
.body(value)
.map_err(|err| Error::Custom(err.into()))
}
3 changes: 2 additions & 1 deletion askama_axum/tests/basic.rs
Expand Up @@ -5,6 +5,7 @@ use axum::{
routing::get,
Router,
};
use http_body_util::BodyExt;
use tower::util::ServiceExt;

#[derive(Template)]
Expand All @@ -30,6 +31,6 @@ async fn template_to_response() {
let headers = res.headers();
assert_eq!(headers["Content-Type"], "text/html; charset=utf-8");

let body = hyper::body::to_bytes(res.into_body()).await.unwrap();
let body = res.into_body().collect().await.unwrap().to_bytes();
assert_eq!(&body[..], b"Hello, world!");
}
8 changes: 2 additions & 6 deletions askama_derive/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "askama_derive"
version = "0.12.2"
version = "0.13.0"
description = "Procedural macro package for Askama"
homepage = "https://github.com/djc/askama"
repository = "https://github.com/djc/askama"
Expand All @@ -23,15 +23,11 @@ serde-yaml = []
num-traits = []
with-actix-web = []
with-axum = []
with-gotham = []
with-hyper = []
with-mendes = []
with-rocket = []
with-tide = []
with-warp = []

[dependencies]
parser = { package = "askama_parser", version = "0.1", path = "../askama_parser" }
parser = { package = "askama_parser", version = "0.2", path = "../askama_parser" }
mime = "0.3"
mime_guess = "2"
proc-macro2 = "1"
Expand Down

0 comments on commit 2b67283

Please sign in to comment.