From 9f66bf5af01d217ce1a68db66a1789a3420e9b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Wed, 8 Jun 2022 12:52:00 +0200 Subject: [PATCH] Merge askama_derive into askama --- Cargo.toml | 2 - askama/Cargo.toml | 36 +++-- {askama_shared => askama}/src/error.rs | 0 {askama_shared => askama}/src/filters/json.rs | 0 {askama_shared => askama}/src/filters/mod.rs | 12 +- {askama_shared => askama}/src/filters/yaml.rs | 0 .../helpers/mod.rs => askama/src/helpers.rs | 0 askama/src/lib.rs | 149 +++++++++++++++++- askama_shared/Cargo.toml | 45 ------ askama_shared/LICENSE-APACHE | 1 - askama_shared/LICENSE-MIT | 1 - askama_shared/README.md | 9 -- askama_shared/src/lib.rs | 147 ----------------- 13 files changed, 172 insertions(+), 230 deletions(-) rename {askama_shared => askama}/src/error.rs (100%) rename {askama_shared => askama}/src/filters/json.rs (100%) rename {askama_shared => askama}/src/filters/mod.rs (98%) rename {askama_shared => askama}/src/filters/yaml.rs (100%) rename askama_shared/src/helpers/mod.rs => askama/src/helpers.rs (100%) delete mode 100644 askama_shared/Cargo.toml delete mode 120000 askama_shared/LICENSE-APACHE delete mode 120000 askama_shared/LICENSE-MIT delete mode 100644 askama_shared/README.md delete mode 100644 askama_shared/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 0907742e5..13f45d8d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,6 @@ members = [ "askama_escape", "askama_mendes", "askama_rocket", - "askama_shared", "askama_tide", "askama_warp", "testing", @@ -18,6 +17,5 @@ default-members = [ "askama", "askama_derive", "askama_escape", - "askama_shared", "testing", ] diff --git a/askama/Cargo.toml b/askama/Cargo.toml index dad6ad784..f580864a0 100644 --- a/askama/Cargo.toml +++ b/askama/Cargo.toml @@ -17,20 +17,20 @@ maintenance = { status = "actively-developed" } [features] default = ["config", "humansize", "num-traits", "urlencode"] -config = ["askama_derive/config", "askama_shared/config"] -humansize = ["askama_derive/humansize", "askama_shared/humansize"] -markdown = ["askama_derive/markdown", "askama_shared/markdown"] -urlencode = ["askama_derive/urlencode", "askama_shared/percent-encoding"] -serde-json = ["askama_derive/serde-json", "askama_shared/json"] -serde-yaml = ["askama_derive/serde-yaml", "askama_shared/yaml"] -num-traits = ["askama_derive/num-traits", "askama_shared/num-traits"] -with-actix-web = ["askama_derive/with-actix-web", "askama_shared/actix-web"] -with-axum = ["askama_derive/with-axum", "askama_shared/axum"] -with-gotham = ["askama_derive/with-gotham", "askama_shared/gotham"] -with-mendes = ["askama_derive/with-mendes", "askama_shared/mendes"] -with-rocket = ["askama_derive/with-rocket", "askama_shared/rocket"] -with-tide = ["askama_derive/with-tide", "askama_shared/tide"] -with-warp = ["askama_derive/with-warp", "askama_shared/warp"] +config = ["askama_derive/config"] +humansize = ["askama_derive/humansize", "dep_humansize"] +markdown = ["askama_derive/markdown", "comrak"] +num-traits = ["askama_derive/num-traits", "dep_num_traits"] +serde-json = ["askama_derive/serde-json", "askama_escape/json", "serde", "serde_json"] +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-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 = [] @@ -39,7 +39,13 @@ mime_guess = [] [dependencies] askama_derive = { version = "0.12.0", path = "../askama_derive" } askama_escape = { version = "0.10.3", path = "../askama_escape" } -askama_shared = { version = "0.13.0", path = "../askama_shared", default-features = false } +comrak = { version = "0.13", optional = true, default-features = false } +dep_humansize = { package = "humansize", version = "1.1.0", optional = true } +dep_num_traits = { package = "num-traits", version = "0.2.6", optional = true } +percent-encoding = { version = "2.1.0", optional = true } +serde = { version = "1.0", optional = true, features = ["derive"] } +serde_json = { version = "1.0", optional = true } +serde_yaml = { version = "0.8", optional = true } [package.metadata.docs.rs] features = ["config", "humansize", "num-traits", "serde-json", "serde-yaml"] diff --git a/askama_shared/src/error.rs b/askama/src/error.rs similarity index 100% rename from askama_shared/src/error.rs rename to askama/src/error.rs diff --git a/askama_shared/src/filters/json.rs b/askama/src/filters/json.rs similarity index 100% rename from askama_shared/src/filters/json.rs rename to askama/src/filters/json.rs diff --git a/askama_shared/src/filters/mod.rs b/askama/src/filters/mod.rs similarity index 98% rename from askama_shared/src/filters/mod.rs rename to askama/src/filters/mod.rs index 17826028f..4350d7096 100644 --- a/askama_shared/src/filters/mod.rs +++ b/askama/src/filters/mod.rs @@ -7,23 +7,23 @@ use std::fmt::{self, Write}; -#[cfg(feature = "serde_json")] +#[cfg(feature = "serde-json")] mod json; -#[cfg(feature = "serde_json")] +#[cfg(feature = "serde-json")] pub use self::json::json; -#[cfg(feature = "serde_yaml")] +#[cfg(feature = "serde-yaml")] mod yaml; -#[cfg(feature = "serde_yaml")] +#[cfg(feature = "serde-yaml")] pub use self::yaml::yaml; #[allow(unused_imports)] use crate::error::Error::Fmt; use askama_escape::{Escaper, MarkupDisplay}; #[cfg(feature = "humansize")] -use humansize::{file_size_opts, FileSize}; +use dep_humansize::{file_size_opts, FileSize}; #[cfg(feature = "num-traits")] -use num_traits::{cast::NumCast, Signed}; +use dep_num_traits::{cast::NumCast, Signed}; #[cfg(feature = "percent-encoding")] use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC}; diff --git a/askama_shared/src/filters/yaml.rs b/askama/src/filters/yaml.rs similarity index 100% rename from askama_shared/src/filters/yaml.rs rename to askama/src/filters/yaml.rs diff --git a/askama_shared/src/helpers/mod.rs b/askama/src/helpers.rs similarity index 100% rename from askama_shared/src/helpers/mod.rs rename to askama/src/helpers.rs diff --git a/askama/src/lib.rs b/askama/src/lib.rs index b0a83ff94..3af97518d 100644 --- a/askama/src/lib.rs +++ b/askama/src/lib.rs @@ -63,11 +63,152 @@ #![deny(elided_lifetimes_in_paths)] #![deny(unreachable_pub)] +mod error; +pub mod filters; +pub mod helpers; + +use std::fmt; + pub use askama_derive::Template; -pub use askama_escape::{Html, Text}; -pub use askama_shared::{ - self as shared, filters, helpers, DynTemplate, Error, MarkupDisplay, Result, Template, -}; +pub use askama_escape::{Html, MarkupDisplay, Text}; + +#[doc(hidden)] +pub use crate as shared; +pub use crate::error::{Error, Result}; + +/// Main `Template` trait; implementations are generally derived +/// +/// If you need an object-safe template, use [`DynTemplate`]. +pub trait Template: fmt::Display { + /// Helper method which allocates a new `String` and renders into it + fn render(&self) -> Result { + let mut buf = String::with_capacity(Self::SIZE_HINT); + self.render_into(&mut buf)?; + Ok(buf) + } + + /// Renders the template to the given `writer` fmt buffer + fn render_into(&self, writer: &mut (impl std::fmt::Write + ?Sized)) -> Result<()>; + + /// Renders the template to the given `writer` io buffer + #[inline] + fn write_into(&self, writer: &mut (impl std::io::Write + ?Sized)) -> std::io::Result<()> { + writer.write_fmt(format_args!("{}", self)) + } + + /// The template's extension, if provided + const EXTENSION: Option<&'static str>; + + /// Provides a conservative estimate of the expanded length of the rendered template + const SIZE_HINT: usize; + + /// The MIME type (Content-Type) of the data that gets rendered by this Template + const MIME_TYPE: &'static str; +} + +/// Object-safe wrapper trait around [`Template`] implementers +/// +/// This trades reduced performance (mostly due to writing into `dyn Write`) for object safety. +pub trait DynTemplate { + /// Helper method which allocates a new `String` and renders into it + fn dyn_render(&self) -> Result; + + /// Renders the template to the given `writer` fmt buffer + fn dyn_render_into(&self, writer: &mut dyn std::fmt::Write) -> Result<()>; + + /// Renders the template to the given `writer` io buffer + fn dyn_write_into(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()>; + + /// Helper function to inspect the template's extension + fn extension(&self) -> Option<&'static str>; + + /// Provides a conservative estimate of the expanded length of the rendered template + fn size_hint(&self) -> usize; + + /// The MIME type (Content-Type) of the data that gets rendered by this Template + fn mime_type(&self) -> &'static str; +} + +impl DynTemplate for T { + fn dyn_render(&self) -> Result { + ::render(self) + } + + fn dyn_render_into(&self, writer: &mut dyn std::fmt::Write) -> Result<()> { + ::render_into(self, writer) + } + + #[inline] + fn dyn_write_into(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> { + writer.write_fmt(format_args!("{}", self)) + } + + fn extension(&self) -> Option<&'static str> { + Self::EXTENSION + } + + fn size_hint(&self) -> usize { + Self::SIZE_HINT + } + + fn mime_type(&self) -> &'static str { + Self::MIME_TYPE + } +} + +impl fmt::Display for dyn DynTemplate { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.dyn_render_into(f).map_err(|_| ::std::fmt::Error {}) + } +} + +#[cfg(test)] +#[allow(clippy::blacklisted_name)] +mod tests { + use std::fmt; + + use super::*; + use crate::{DynTemplate, Template}; + + #[test] + fn dyn_template() { + struct Test; + impl Template for Test { + fn render_into(&self, writer: &mut (impl std::fmt::Write + ?Sized)) -> Result<()> { + Ok(writer.write_str("test")?) + } + + const EXTENSION: Option<&'static str> = Some("txt"); + + const SIZE_HINT: usize = 4; + + const MIME_TYPE: &'static str = "text/plain; charset=utf-8"; + } + + impl fmt::Display for Test { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.render_into(f).map_err(|_| fmt::Error {}) + } + } + + fn render(t: &dyn DynTemplate) -> String { + t.dyn_render().unwrap() + } + + let test = &Test as &dyn DynTemplate; + + assert_eq!(render(test), "test"); + + assert_eq!(test.to_string(), "test"); + + assert_eq!(format!("{}", test), "test"); + + let mut vec = Vec::new(); + test.dyn_write_into(&mut vec).unwrap(); + assert_eq!(vec, vec![b't', b'e', b's', b't']); + } +} /// Old build script helper to rebuild crates if contained templates have changed /// diff --git a/askama_shared/Cargo.toml b/askama_shared/Cargo.toml deleted file mode 100644 index 0a2cb2115..000000000 --- a/askama_shared/Cargo.toml +++ /dev/null @@ -1,45 +0,0 @@ -[package] -name = "askama_shared" -version = "0.13.0" -description = "Shared code for Askama" -homepage = "https://github.com/djc/askama" -repository = "https://github.com/djc/askama" -license = "MIT/Apache-2.0" -workspace = ".." -readme = "README.md" -edition = "2018" - -[features] -default = ["config", "humansize", "num-traits", "percent-encoding"] -config = ["serde", "toml"] -json = ["serde", "serde_json", "askama_escape/json"] -markdown = ["comrak"] -yaml = ["serde", "serde_yaml"] - -actix-web = [] -axum = [] -gotham = [] -mendes = [] -rocket = [] -tide = [] -warp = [] - -[dependencies] -askama_escape = { version = "0.10.3", path = "../askama_escape" } -comrak = { version = "0.13", optional = true, default-features = false } -humansize = { version = "1.1.0", optional = true } -mime = "0.3" -mime_guess = "2" -nom = "7" -num-traits = { version = "0.2.6", optional = true } -proc-macro2 = "1" -quote = "1" -serde = { version = "1.0", optional = true, features = ["derive"] } -serde_json = { version = "1.0", optional = true } -serde_yaml = { version = "0.8", optional = true } -syn = "1" -toml = { version = "0.5", optional = true } -percent-encoding = { version = "2.1.0", optional = true } - -[package.metadata.docs.rs] -features = ["config", "humansize", "num-traits", "json", "yaml", "percent-encoding"] diff --git a/askama_shared/LICENSE-APACHE b/askama_shared/LICENSE-APACHE deleted file mode 120000 index 76219eb72..000000000 --- a/askama_shared/LICENSE-APACHE +++ /dev/null @@ -1 +0,0 @@ -../LICENSE-MIT \ No newline at end of file diff --git a/askama_shared/LICENSE-MIT b/askama_shared/LICENSE-MIT deleted file mode 120000 index 76219eb72..000000000 --- a/askama_shared/LICENSE-MIT +++ /dev/null @@ -1 +0,0 @@ -../LICENSE-MIT \ No newline at end of file diff --git a/askama_shared/README.md b/askama_shared/README.md deleted file mode 100644 index 21b4a962f..000000000 --- a/askama_shared/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# askama_shared: shared code for the Askama templating engine - -[![Documentation](https://docs.rs/askama_shared/badge.svg)](https://docs.rs/askama_shared/) -[![Latest version](https://img.shields.io/crates/v/askama_shared.svg)](https://crates.io/crates/askama_shared) -[![Build Status](https://github.com/djc/askama/workflows/CI/badge.svg)](https://github.com/djc/askama/actions?query=workflow%3ACI) -[![Chat](https://badges.gitter.im/gitterHQ/gitter.svg)](https://gitter.im/djc/askama) - -This crate contains helper code used by the [Askama](https://github.com/djc/askama) -templating engine. diff --git a/askama_shared/src/lib.rs b/askama_shared/src/lib.rs deleted file mode 100644 index cb2640681..000000000 --- a/askama_shared/src/lib.rs +++ /dev/null @@ -1,147 +0,0 @@ -#![cfg_attr(feature = "cargo-clippy", allow(unused_parens))] -#![forbid(unsafe_code)] -#![deny(elided_lifetimes_in_paths)] -#![deny(unreachable_pub)] - -use std::fmt; - -pub use askama_escape::MarkupDisplay; - -mod error; -pub use crate::error::{Error, Result}; -pub mod filters; -pub mod helpers; - -/// Main `Template` trait; implementations are generally derived -/// -/// If you need an object-safe template, use [`DynTemplate`]. -pub trait Template: fmt::Display { - /// Helper method which allocates a new `String` and renders into it - fn render(&self) -> Result { - let mut buf = String::with_capacity(Self::SIZE_HINT); - self.render_into(&mut buf)?; - Ok(buf) - } - - /// Renders the template to the given `writer` fmt buffer - fn render_into(&self, writer: &mut (impl std::fmt::Write + ?Sized)) -> Result<()>; - - /// Renders the template to the given `writer` io buffer - #[inline] - fn write_into(&self, writer: &mut (impl std::io::Write + ?Sized)) -> std::io::Result<()> { - writer.write_fmt(format_args!("{}", self)) - } - - /// The template's extension, if provided - const EXTENSION: Option<&'static str>; - - /// Provides a conservative estimate of the expanded length of the rendered template - const SIZE_HINT: usize; - - /// The MIME type (Content-Type) of the data that gets rendered by this Template - const MIME_TYPE: &'static str; -} - -/// Object-safe wrapper trait around [`Template`] implementers -/// -/// This trades reduced performance (mostly due to writing into `dyn Write`) for object safety. -pub trait DynTemplate { - /// Helper method which allocates a new `String` and renders into it - fn dyn_render(&self) -> Result; - - /// Renders the template to the given `writer` fmt buffer - fn dyn_render_into(&self, writer: &mut dyn std::fmt::Write) -> Result<()>; - - /// Renders the template to the given `writer` io buffer - fn dyn_write_into(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()>; - - /// Helper function to inspect the template's extension - fn extension(&self) -> Option<&'static str>; - - /// Provides a conservative estimate of the expanded length of the rendered template - fn size_hint(&self) -> usize; - - /// The MIME type (Content-Type) of the data that gets rendered by this Template - fn mime_type(&self) -> &'static str; -} - -impl DynTemplate for T { - fn dyn_render(&self) -> Result { - ::render(self) - } - - fn dyn_render_into(&self, writer: &mut dyn std::fmt::Write) -> Result<()> { - ::render_into(self, writer) - } - - #[inline] - fn dyn_write_into(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> { - writer.write_fmt(format_args!("{}", self)) - } - - fn extension(&self) -> Option<&'static str> { - Self::EXTENSION - } - - fn size_hint(&self) -> usize { - Self::SIZE_HINT - } - - fn mime_type(&self) -> &'static str { - Self::MIME_TYPE - } -} - -impl fmt::Display for dyn DynTemplate { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.dyn_render_into(f).map_err(|_| ::std::fmt::Error {}) - } -} - -#[cfg(test)] -#[allow(clippy::blacklisted_name)] -mod tests { - use std::fmt; - - use super::*; - use crate::{DynTemplate, Template}; - - #[test] - fn dyn_template() { - struct Test; - impl Template for Test { - fn render_into(&self, writer: &mut (impl std::fmt::Write + ?Sized)) -> Result<()> { - Ok(writer.write_str("test")?) - } - - const EXTENSION: Option<&'static str> = Some("txt"); - - const SIZE_HINT: usize = 4; - - const MIME_TYPE: &'static str = "text/plain; charset=utf-8"; - } - - impl fmt::Display for Test { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.render_into(f).map_err(|_| fmt::Error {}) - } - } - - fn render(t: &dyn DynTemplate) -> String { - t.dyn_render().unwrap() - } - - let test = &Test as &dyn DynTemplate; - - assert_eq!(render(test), "test"); - - assert_eq!(test.to_string(), "test"); - - assert_eq!(format!("{}", test), "test"); - - let mut vec = Vec::new(); - test.dyn_write_into(&mut vec).unwrap(); - assert_eq!(vec, vec![b't', b'e', b's', b't']); - } -}