From cddd476f1ae04158710aceab18d91d283442dba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Tue, 24 Sep 2024 01:07:38 +0200 Subject: [PATCH 1/9] derive: restrict list to needed entries --- rinja_derive/src/lib.rs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/rinja_derive/src/lib.rs b/rinja_derive/src/lib.rs index 2ade2efe..60327354 100644 --- a/rinja_derive/src/lib.rs +++ b/rinja_derive/src/lib.rs @@ -380,28 +380,17 @@ impl fmt::Display for MsgValidEscapers<'_> { } // This is used by the code generator to decide whether a named filter is part of -// Rinja or should refer to a local `filters` module. It should contain all the -// filters shipped with Rinja, even the optional ones (since optional inclusion -// in the const vector based on features seems impossible right now). +// Rinja or should refer to a local `filters` module. const BUILT_IN_FILTERS: &[&str] = &[ "abs", "capitalize", "center", - "e", - "escape", "filesizeformat", - "fmt", - "format", "indent", "into_f64", "into_isize", - "join", - "linebreaks", - "linebreaksbr", "lower", "lowercase", - "paragraphbreaks", - "safe", "title", "trim", "truncate", @@ -410,8 +399,6 @@ const BUILT_IN_FILTERS: &[&str] = &[ "urlencode_strict", "urlencode", "wordcount", - // optional features, reserve the names anyway: - "json", ]; const CRATE: &str = if cfg!(feature = "with-actix-web") { From 8fbc0ba9242404d01b44539775cf33d29c74171d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Tue, 24 Sep 2024 01:20:23 +0200 Subject: [PATCH 2/9] derive: give proper error message if `num-traits` feature is missing --- rinja/src/filters/builtin.rs | 66 --------------------------------- rinja/src/filters/mod.rs | 6 ++- rinja/src/filters/num_traits.rs | 53 ++++++++++++++++++++++++++ rinja_derive/src/generator.rs | 27 ++++++++++++++ rinja_derive/src/lib.rs | 3 -- 5 files changed, 84 insertions(+), 71 deletions(-) create mode 100644 rinja/src/filters/num_traits.rs diff --git a/rinja/src/filters/builtin.rs b/rinja/src/filters/builtin.rs index 647489f6..03b89c36 100644 --- a/rinja/src/filters/builtin.rs +++ b/rinja/src/filters/builtin.rs @@ -4,8 +4,6 @@ use std::fmt::{self, Write}; #[cfg(feature = "humansize")] use humansize::{ISizeFormatter, ToF64, DECIMAL}; -#[cfg(feature = "num-traits")] -use num_traits::{cast::NumCast, Signed}; #[cfg(feature = "urlencode")] use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC}; @@ -381,24 +379,6 @@ pub fn indent(s: impl fmt::Display, width: usize) -> Result indent(try_to_string(s)?, width) } -#[cfg(feature = "num-traits")] -/// Casts number to f64 -pub fn into_f64(number: T) -> Result -where - T: NumCast, -{ - number.to_f64().ok_or(Error::Fmt) -} - -#[cfg(feature = "num-traits")] -/// Casts number to isize -pub fn into_isize(number: T) -> Result -where - T: NumCast, -{ - number.to_isize().ok_or(Error::Fmt) -} - /// Joins iterable into a string separated by provided argument #[inline] pub fn join(input: I, separator: S) -> Result, Infallible> @@ -444,15 +424,6 @@ where } } -#[cfg(feature = "num-traits")] -/// Absolute value -pub fn abs(number: T) -> Result -where - T: Signed, -{ - Ok(number.abs()) -} - /// Capitalize a value. The first character will be uppercase, all others lowercase. #[inline] pub fn capitalize(s: impl fmt::Display) -> Result { @@ -932,31 +903,6 @@ mod tests { ); } - #[cfg(feature = "num-traits")] - #[test] - #[allow(clippy::float_cmp)] - fn test_into_f64() { - assert_eq!(into_f64(1).unwrap(), 1.0_f64); - assert_eq!(into_f64(1.9).unwrap(), 1.9_f64); - assert_eq!(into_f64(-1.9).unwrap(), -1.9_f64); - assert_eq!(into_f64(f32::INFINITY).unwrap(), f64::INFINITY); - assert_eq!(into_f64(-f32::INFINITY).unwrap(), -f64::INFINITY); - } - - #[cfg(feature = "num-traits")] - #[test] - fn test_into_isize() { - assert_eq!(into_isize(1).unwrap(), 1_isize); - assert_eq!(into_isize(1.9).unwrap(), 1_isize); - assert_eq!(into_isize(-1.9).unwrap(), -1_isize); - assert_eq!(into_isize(1.5_f64).unwrap(), 1_isize); - assert_eq!(into_isize(-1.5_f64).unwrap(), -1_isize); - match into_isize(f64::INFINITY) { - Err(Error::Fmt) => {} - _ => panic!("Should return error of type Err(Error::Fmt)"), - }; - } - #[allow(clippy::needless_borrow)] #[test] fn test_join() { @@ -992,18 +938,6 @@ mod tests { ); } - #[cfg(feature = "num-traits")] - #[test] - #[allow(clippy::float_cmp)] - fn test_abs() { - assert_eq!(abs(1).unwrap(), 1); - assert_eq!(abs(-1).unwrap(), 1); - assert_eq!(abs(1.0).unwrap(), 1.0); - assert_eq!(abs(-1.0).unwrap(), 1.0); - assert_eq!(abs(1.0_f64).unwrap(), 1.0_f64); - assert_eq!(abs(-1.0_f64).unwrap(), 1.0_f64); - } - #[test] fn test_capitalize() { assert_eq!(capitalize("foo").unwrap().to_string(), "Foo".to_string()); diff --git a/rinja/src/filters/mod.rs b/rinja/src/filters/mod.rs index af4ff2e4..e566942b 100644 --- a/rinja/src/filters/mod.rs +++ b/rinja/src/filters/mod.rs @@ -14,11 +14,11 @@ mod builtin; mod escape; #[cfg(feature = "serde_json")] mod json; +#[cfg(feature = "num-traits")] +mod num_traits; #[cfg(feature = "humansize")] pub use builtin::filesizeformat; -#[cfg(feature = "num-traits")] -pub use builtin::{abs, into_f64, into_isize}; pub use builtin::{ capitalize, center, fmt, format, indent, join, linebreaks, linebreaksbr, lower, lowercase, paragraphbreaks, pluralize, title, trim, truncate, upper, uppercase, wordcount, PluralizeCount, @@ -31,3 +31,5 @@ pub use escape::{ }; #[cfg(feature = "serde_json")] pub use json::{json, json_pretty, AsIndent}; +#[cfg(feature = "num-traits")] +pub use num_traits::{abs, into_f64, into_isize}; diff --git a/rinja/src/filters/num_traits.rs b/rinja/src/filters/num_traits.rs new file mode 100644 index 00000000..f42a7475 --- /dev/null +++ b/rinja/src/filters/num_traits.rs @@ -0,0 +1,53 @@ +use num_traits::cast::NumCast; +use num_traits::Signed; + +use crate::{Error, Result}; + +/// Absolute value +pub fn abs(number: T) -> Result { + Ok(number.abs()) +} + +/// Casts number to f64 +pub fn into_f64(number: T) -> Result { + number.to_f64().ok_or(Error::Fmt) +} + +/// Casts number to isize +pub fn into_isize(number: T) -> Result { + number.to_isize().ok_or(Error::Fmt) +} + +#[test] +#[allow(clippy::float_cmp)] +fn test_abs() { + assert_eq!(abs(1).unwrap(), 1); + assert_eq!(abs(-1).unwrap(), 1); + assert_eq!(abs(1.0).unwrap(), 1.0); + assert_eq!(abs(-1.0).unwrap(), 1.0); + assert_eq!(abs(1.0_f64).unwrap(), 1.0_f64); + assert_eq!(abs(-1.0_f64).unwrap(), 1.0_f64); +} + +#[test] +#[allow(clippy::float_cmp)] +fn test_into_f64() { + assert_eq!(into_f64(1).unwrap(), 1.0_f64); + assert_eq!(into_f64(1.9).unwrap(), 1.9_f64); + assert_eq!(into_f64(-1.9).unwrap(), -1.9_f64); + assert_eq!(into_f64(f32::INFINITY).unwrap(), f64::INFINITY); + assert_eq!(into_f64(-f32::INFINITY).unwrap(), -f64::INFINITY); +} + +#[test] +fn test_into_isize() { + assert_eq!(into_isize(1).unwrap(), 1_isize); + assert_eq!(into_isize(1.9).unwrap(), 1_isize); + assert_eq!(into_isize(-1.9).unwrap(), -1_isize); + assert_eq!(into_isize(1.5_f64).unwrap(), 1_isize); + assert_eq!(into_isize(-1.5_f64).unwrap(), -1_isize); + match into_isize(f64::INFINITY) { + Err(Error::Fmt) => {} + _ => panic!("Should return error of type Err(Error::Fmt)"), + }; +} diff --git a/rinja_derive/src/generator.rs b/rinja_derive/src/generator.rs index 36fbacca..c05a80ea 100644 --- a/rinja_derive/src/generator.rs +++ b/rinja_derive/src/generator.rs @@ -1537,6 +1537,9 @@ impl<'a> Generator<'a> { filter: &WithSpan<'_, T>, ) -> Result { match name { + "abs" | "into_f64" | "into_isize" => { + return self._visit_num_traits(ctx, buf, name, args, filter); + } "deref" => return self._visit_deref_filter(ctx, buf, args, filter), "escape" | "e" => return self._visit_escape_filter(ctx, buf, args, filter), "fmt" => return self._visit_fmt_filter(ctx, buf, args, filter), @@ -1562,6 +1565,30 @@ impl<'a> Generator<'a> { Ok(DisplayWrap::Unwrapped) } + fn _visit_num_traits( + &mut self, + ctx: &Context<'_>, + buf: &mut Buffer, + name: &str, + args: &[WithSpan<'_, Expr<'_>>], + node: &WithSpan<'_, T>, + ) -> Result { + if cfg!(not(feature = "num-traits")) { + return Err(ctx.generate_error( + &format!("the `{name}` filter requires the `num-traits` feature to be enabled"), + node, + )); + } + + // All filters return numbers, and any default formatted number is HTML safe. + buf.write(format_args!( + "{CRATE}::filters::HtmlSafeOutput({CRATE}::filters::{name}(", + )); + self._visit_args(ctx, buf, args)?; + buf.write(")?)"); + Ok(DisplayWrap::Unwrapped) + } + fn _visit_pluralize_filter( &mut self, ctx: &Context<'_>, diff --git a/rinja_derive/src/lib.rs b/rinja_derive/src/lib.rs index 60327354..063eb4b7 100644 --- a/rinja_derive/src/lib.rs +++ b/rinja_derive/src/lib.rs @@ -382,13 +382,10 @@ impl fmt::Display for MsgValidEscapers<'_> { // This is used by the code generator to decide whether a named filter is part of // Rinja or should refer to a local `filters` module. const BUILT_IN_FILTERS: &[&str] = &[ - "abs", "capitalize", "center", "filesizeformat", "indent", - "into_f64", - "into_isize", "lower", "lowercase", "title", From 16d15d2c172989e59d5342b5e2c7122c323a69ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Tue, 24 Sep 2024 01:25:16 +0200 Subject: [PATCH 3/9] derive: give proper error message if `humansize` feature is missing --- rinja/src/filters/builtin.rs | 46 ---------------------------------- rinja/src/filters/humansize.rs | 44 ++++++++++++++++++++++++++++++++ rinja/src/filters/mod.rs | 6 +++-- rinja_derive/src/generator.rs | 27 ++++++++++++++++++++ rinja_derive/src/lib.rs | 1 - 5 files changed, 75 insertions(+), 49 deletions(-) create mode 100644 rinja/src/filters/humansize.rs diff --git a/rinja/src/filters/builtin.rs b/rinja/src/filters/builtin.rs index 03b89c36..d5525973 100644 --- a/rinja/src/filters/builtin.rs +++ b/rinja/src/filters/builtin.rs @@ -2,8 +2,6 @@ use std::cell::Cell; use std::convert::Infallible; use std::fmt::{self, Write}; -#[cfg(feature = "humansize")] -use humansize::{ISizeFormatter, ToF64, DECIMAL}; #[cfg(feature = "urlencode")] use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC}; @@ -27,40 +25,6 @@ const URLENCODE_SET: &AsciiSet = &URLENCODE_STRICT_SET.remove(b'/'); // MAX_LEN is maximum allowed length for filters. const MAX_LEN: usize = 10_000; -#[cfg(feature = "humansize")] -/// Returns adequate string representation (in KB, ..) of number of bytes -/// -/// ## Example -/// ``` -/// # use rinja::Template; -/// #[derive(Template)] -/// #[template( -/// source = "Filesize: {{ size_in_bytes|filesizeformat }}.", -/// ext = "html" -/// )] -/// struct Example { -/// size_in_bytes: u64, -/// } -/// -/// let tmpl = Example { size_in_bytes: 1_234_567 }; -/// assert_eq!(tmpl.to_string(), "Filesize: 1.23 MB."); -/// ``` -#[inline] -pub fn filesizeformat(b: &impl ToF64) -> Result { - Ok(FilesizeFormatFilter(b.to_f64())) -} - -#[cfg(feature = "humansize")] -#[derive(Debug, Clone, Copy)] -pub struct FilesizeFormatFilter(f64); - -#[cfg(feature = "humansize")] -impl fmt::Display for FilesizeFormatFilter { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_fmt(format_args!("{}", ISizeFormatter::new(self.0, &DECIMAL))) - } -} - #[cfg(feature = "urlencode")] /// Percent-encodes the argument for safe use in URI; does not encode `/`. /// @@ -743,16 +707,6 @@ fn try_to_string(s: impl fmt::Display) -> Result { mod tests { use super::*; - #[cfg(feature = "humansize")] - #[test] - fn test_filesizeformat() { - assert_eq!(filesizeformat(&0).unwrap().to_string(), "0 B"); - assert_eq!(filesizeformat(&999u64).unwrap().to_string(), "999 B"); - assert_eq!(filesizeformat(&1000i32).unwrap().to_string(), "1 kB"); - assert_eq!(filesizeformat(&1023).unwrap().to_string(), "1.02 kB"); - assert_eq!(filesizeformat(&1024usize).unwrap().to_string(), "1.02 kB"); - } - #[cfg(feature = "urlencode")] #[test] fn test_urlencoding() { diff --git a/rinja/src/filters/humansize.rs b/rinja/src/filters/humansize.rs new file mode 100644 index 00000000..bbec1c8b --- /dev/null +++ b/rinja/src/filters/humansize.rs @@ -0,0 +1,44 @@ +use std::convert::Infallible; +use std::fmt; + +use humansize::{ISizeFormatter, ToF64, DECIMAL}; + +/// Returns adequate string representation (in KB, ..) of number of bytes +/// +/// ## Example +/// ``` +/// # use rinja::Template; +/// #[derive(Template)] +/// #[template( +/// source = "Filesize: {{ size_in_bytes|filesizeformat }}.", +/// ext = "html" +/// )] +/// struct Example { +/// size_in_bytes: u64, +/// } +/// +/// let tmpl = Example { size_in_bytes: 1_234_567 }; +/// assert_eq!(tmpl.to_string(), "Filesize: 1.23 MB."); +/// ``` +#[inline] +pub fn filesizeformat(b: &impl ToF64) -> Result { + Ok(FilesizeFormatFilter(b.to_f64())) +} + +#[derive(Debug, Clone, Copy)] +pub struct FilesizeFormatFilter(f64); + +impl fmt::Display for FilesizeFormatFilter { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_fmt(format_args!("{}", ISizeFormatter::new(self.0, &DECIMAL))) + } +} + +#[test] +fn test_filesizeformat() { + assert_eq!(filesizeformat(&0).unwrap().to_string(), "0 B"); + assert_eq!(filesizeformat(&999u64).unwrap().to_string(), "999 B"); + assert_eq!(filesizeformat(&1000i32).unwrap().to_string(), "1 kB"); + assert_eq!(filesizeformat(&1023).unwrap().to_string(), "1.02 kB"); + assert_eq!(filesizeformat(&1024usize).unwrap().to_string(), "1.02 kB"); +} diff --git a/rinja/src/filters/mod.rs b/rinja/src/filters/mod.rs index e566942b..c60fcbe0 100644 --- a/rinja/src/filters/mod.rs +++ b/rinja/src/filters/mod.rs @@ -12,13 +12,13 @@ mod builtin; mod escape; +#[cfg(feature = "humansize")] +mod humansize; #[cfg(feature = "serde_json")] mod json; #[cfg(feature = "num-traits")] mod num_traits; -#[cfg(feature = "humansize")] -pub use builtin::filesizeformat; pub use builtin::{ capitalize, center, fmt, format, indent, join, linebreaks, linebreaksbr, lower, lowercase, paragraphbreaks, pluralize, title, trim, truncate, upper, uppercase, wordcount, PluralizeCount, @@ -29,6 +29,8 @@ pub use escape::{ e, escape, safe, AutoEscape, AutoEscaper, Escaper, FastWritable, Html, HtmlSafe, HtmlSafeOutput, MaybeSafe, Safe, Text, Unsafe, Writable, WriteWritable, }; +#[cfg(feature = "humansize")] +pub use humansize::filesizeformat; #[cfg(feature = "serde_json")] pub use json::{json, json_pretty, AsIndent}; #[cfg(feature = "num-traits")] diff --git a/rinja_derive/src/generator.rs b/rinja_derive/src/generator.rs index c05a80ea..db6c54f5 100644 --- a/rinja_derive/src/generator.rs +++ b/rinja_derive/src/generator.rs @@ -1542,6 +1542,9 @@ impl<'a> Generator<'a> { } "deref" => return self._visit_deref_filter(ctx, buf, args, filter), "escape" | "e" => return self._visit_escape_filter(ctx, buf, args, filter), + "filesizeformat" => { + return self._visit_humansize(ctx, buf, name, args, filter); + } "fmt" => return self._visit_fmt_filter(ctx, buf, args, filter), "format" => return self._visit_format_filter(ctx, buf, args, filter), "join" => return self._visit_join_filter(ctx, buf, args), @@ -1565,6 +1568,30 @@ impl<'a> Generator<'a> { Ok(DisplayWrap::Unwrapped) } + fn _visit_humansize( + &mut self, + ctx: &Context<'_>, + buf: &mut Buffer, + name: &str, + args: &[WithSpan<'_, Expr<'_>>], + node: &WithSpan<'_, T>, + ) -> Result { + if cfg!(not(feature = "humansize")) { + return Err(ctx.generate_error( + &format!("the `{name}` filter requires the `humansize` feature to be enabled"), + node, + )); + } + + // All filters return numbers, and any default formatted number is HTML safe. + buf.write(format_args!( + "{CRATE}::filters::HtmlSafeOutput({CRATE}::filters::{name}(", + )); + self._visit_args(ctx, buf, args)?; + buf.write(")?)"); + Ok(DisplayWrap::Unwrapped) + } + fn _visit_num_traits( &mut self, ctx: &Context<'_>, diff --git a/rinja_derive/src/lib.rs b/rinja_derive/src/lib.rs index 063eb4b7..f841e603 100644 --- a/rinja_derive/src/lib.rs +++ b/rinja_derive/src/lib.rs @@ -384,7 +384,6 @@ impl fmt::Display for MsgValidEscapers<'_> { const BUILT_IN_FILTERS: &[&str] = &[ "capitalize", "center", - "filesizeformat", "indent", "lower", "lowercase", From ecdf50a39653d6d2dc9e603357a51d6ef9c22dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Tue, 24 Sep 2024 01:34:39 +0200 Subject: [PATCH 4/9] derive: give proper error message if `urlencode` feature is missing --- rinja/src/filters/builtin.rs | 138 --------------------------------- rinja/src/filters/mod.rs | 6 +- rinja/src/filters/urlencode.rs | 132 +++++++++++++++++++++++++++++++ rinja_derive/src/generator.rs | 27 +++++++ rinja_derive/src/lib.rs | 2 - 5 files changed, 163 insertions(+), 142 deletions(-) create mode 100644 rinja/src/filters/urlencode.rs diff --git a/rinja/src/filters/builtin.rs b/rinja/src/filters/builtin.rs index d5525973..773019d7 100644 --- a/rinja/src/filters/builtin.rs +++ b/rinja/src/filters/builtin.rs @@ -2,104 +2,12 @@ use std::cell::Cell; use std::convert::Infallible; use std::fmt::{self, Write}; -#[cfg(feature = "urlencode")] -use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC}; - use super::escape::{FastWritable, HtmlSafeOutput}; use crate::{Error, Result}; -#[cfg(feature = "urlencode")] -// Urlencode char encoding set. Only the characters in the unreserved set don't -// have any special purpose in any part of a URI and can be safely left -// unencoded as specified in https://tools.ietf.org/html/rfc3986.html#section-2.3 -const URLENCODE_STRICT_SET: &AsciiSet = &NON_ALPHANUMERIC - .remove(b'_') - .remove(b'.') - .remove(b'-') - .remove(b'~'); - -#[cfg(feature = "urlencode")] -// Same as URLENCODE_STRICT_SET, but preserves forward slashes for encoding paths -const URLENCODE_SET: &AsciiSet = &URLENCODE_STRICT_SET.remove(b'/'); - // MAX_LEN is maximum allowed length for filters. const MAX_LEN: usize = 10_000; -#[cfg(feature = "urlencode")] -/// Percent-encodes the argument for safe use in URI; does not encode `/`. -/// -/// This should be safe for all parts of URI (paths segments, query keys, query -/// values). In the rare case that the server can't deal with forward slashes in -/// the query string, use [`urlencode_strict`], which encodes them as well. -/// -/// Encodes all characters except ASCII letters, digits, and `_.-~/`. In other -/// words, encodes all characters which are not in the unreserved set, -/// as specified by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.3), -/// with the exception of `/`. -/// -/// ```none,ignore -/// Station -/// Page -/// ``` -/// -/// To encode `/` as well, see [`urlencode_strict`](./fn.urlencode_strict.html). -/// -/// [`urlencode_strict`]: ./fn.urlencode_strict.html -#[inline] -pub fn urlencode(s: T) -> Result>, Infallible> { - Ok(HtmlSafeOutput(UrlencodeFilter(s, URLENCODE_SET))) -} - -#[cfg(feature = "urlencode")] -/// Percent-encodes the argument for safe use in URI; encodes `/`. -/// -/// Use this filter for encoding query keys and values in the rare case that -/// the server can't process them unencoded. -/// -/// Encodes all characters except ASCII letters, digits, and `_.-~`. In other -/// words, encodes all characters which are not in the unreserved set, -/// as specified by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.3). -/// -/// ```none,ignore -/// Page -/// ``` -/// -/// If you want to preserve `/`, see [`urlencode`](./fn.urlencode.html). -#[inline] -pub fn urlencode_strict(s: T) -> Result>, Infallible> { - Ok(HtmlSafeOutput(UrlencodeFilter(s, URLENCODE_STRICT_SET))) -} - -#[cfg(feature = "urlencode")] -pub struct UrlencodeFilter(pub T, pub &'static AsciiSet); - -#[cfg(feature = "urlencode")] -impl fmt::Display for UrlencodeFilter { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(UrlencodeWriter(f, self.1), "{}", self.0) - } -} - -#[cfg(feature = "urlencode")] -impl FastWritable for UrlencodeFilter { - #[inline] - fn write_into(&self, f: &mut W) -> fmt::Result { - self.0.write_into(&mut UrlencodeWriter(f, self.1)) - } -} - -#[cfg(feature = "urlencode")] -struct UrlencodeWriter(W, &'static AsciiSet); - -#[cfg(feature = "urlencode")] -impl fmt::Write for UrlencodeWriter { - #[inline] - fn write_str(&mut self, s: &str) -> fmt::Result { - write!(self.0, "{}", utf8_percent_encode(s, self.1)) - } -} - /// Formats arguments according to the specified format /// /// The *second* argument to this filter must be a string literal (as in normal @@ -707,52 +615,6 @@ fn try_to_string(s: impl fmt::Display) -> Result { mod tests { use super::*; - #[cfg(feature = "urlencode")] - #[test] - fn test_urlencoding() { - // Unreserved (https://tools.ietf.org/html/rfc3986.html#section-2.3) - // alpha / digit - assert_eq!(urlencode("AZaz09").unwrap().to_string(), "AZaz09"); - assert_eq!(urlencode_strict("AZaz09").unwrap().to_string(), "AZaz09"); - // other - assert_eq!(urlencode("_.-~").unwrap().to_string(), "_.-~"); - assert_eq!(urlencode_strict("_.-~").unwrap().to_string(), "_.-~"); - - // Reserved (https://tools.ietf.org/html/rfc3986.html#section-2.2) - // gen-delims - assert_eq!( - urlencode(":/?#[]@").unwrap().to_string(), - "%3A/%3F%23%5B%5D%40" - ); - assert_eq!( - urlencode_strict(":/?#[]@").unwrap().to_string(), - "%3A%2F%3F%23%5B%5D%40" - ); - // sub-delims - assert_eq!( - urlencode("!$&'()*+,;=").unwrap().to_string(), - "%21%24%26%27%28%29%2A%2B%2C%3B%3D" - ); - assert_eq!( - urlencode_strict("!$&'()*+,;=").unwrap().to_string(), - "%21%24%26%27%28%29%2A%2B%2C%3B%3D" - ); - - // Other - assert_eq!( - urlencode("žŠďŤňĚáÉóŮ").unwrap().to_string(), - "%C5%BE%C5%A0%C4%8F%C5%A4%C5%88%C4%9A%C3%A1%C3%89%C3%B3%C5%AE" - ); - assert_eq!( - urlencode_strict("žŠďŤňĚáÉóŮ").unwrap().to_string(), - "%C5%BE%C5%A0%C4%8F%C5%A4%C5%88%C4%9A%C3%A1%C3%89%C3%B3%C5%AE" - ); - - // Ferris - assert_eq!(urlencode("🦀").unwrap().to_string(), "%F0%9F%A6%80"); - assert_eq!(urlencode_strict("🦀").unwrap().to_string(), "%F0%9F%A6%80"); - } - #[test] fn test_linebreaks() { assert_eq!( diff --git a/rinja/src/filters/mod.rs b/rinja/src/filters/mod.rs index c60fcbe0..b0a93564 100644 --- a/rinja/src/filters/mod.rs +++ b/rinja/src/filters/mod.rs @@ -18,13 +18,13 @@ mod humansize; mod json; #[cfg(feature = "num-traits")] mod num_traits; +#[cfg(feature = "urlencode")] +mod urlencode; pub use builtin::{ capitalize, center, fmt, format, indent, join, linebreaks, linebreaksbr, lower, lowercase, paragraphbreaks, pluralize, title, trim, truncate, upper, uppercase, wordcount, PluralizeCount, }; -#[cfg(feature = "urlencode")] -pub use builtin::{urlencode, urlencode_strict}; pub use escape::{ e, escape, safe, AutoEscape, AutoEscaper, Escaper, FastWritable, Html, HtmlSafe, HtmlSafeOutput, MaybeSafe, Safe, Text, Unsafe, Writable, WriteWritable, @@ -35,3 +35,5 @@ pub use humansize::filesizeformat; pub use json::{json, json_pretty, AsIndent}; #[cfg(feature = "num-traits")] pub use num_traits::{abs, into_f64, into_isize}; +#[cfg(feature = "urlencode")] +pub use urlencode::{urlencode, urlencode_strict}; diff --git a/rinja/src/filters/urlencode.rs b/rinja/src/filters/urlencode.rs new file mode 100644 index 00000000..10acdce4 --- /dev/null +++ b/rinja/src/filters/urlencode.rs @@ -0,0 +1,132 @@ +use std::convert::Infallible; +use std::fmt; +use std::fmt::Write; + +use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC}; + +use crate::filters::{FastWritable, HtmlSafeOutput}; + +// Urlencode char encoding set. Only the characters in the unreserved set don't +// have any special purpose in any part of a URI and can be safely left +// unencoded as specified in https://tools.ietf.org/html/rfc3986.html#section-2.3 +const URLENCODE_STRICT_SET: &AsciiSet = &NON_ALPHANUMERIC + .remove(b'_') + .remove(b'.') + .remove(b'-') + .remove(b'~'); + +// Same as URLENCODE_STRICT_SET, but preserves forward slashes for encoding paths +const URLENCODE_SET: &AsciiSet = &URLENCODE_STRICT_SET.remove(b'/'); + +/// Percent-encodes the argument for safe use in URI; does not encode `/`. +/// +/// This should be safe for all parts of URI (paths segments, query keys, query +/// values). In the rare case that the server can't deal with forward slashes in +/// the query string, use [`urlencode_strict`], which encodes them as well. +/// +/// Encodes all characters except ASCII letters, digits, and `_.-~/`. In other +/// words, encodes all characters which are not in the unreserved set, +/// as specified by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.3), +/// with the exception of `/`. +/// +/// ```none,ignore +/// Station +/// Page +/// ``` +/// +/// To encode `/` as well, see [`urlencode_strict`](./fn.urlencode_strict.html). +/// +/// [`urlencode_strict`]: ./fn.urlencode_strict.html +#[inline] +pub fn urlencode(s: T) -> Result>, Infallible> { + Ok(HtmlSafeOutput(UrlencodeFilter(s, URLENCODE_SET))) +} + +/// Percent-encodes the argument for safe use in URI; encodes `/`. +/// +/// Use this filter for encoding query keys and values in the rare case that +/// the server can't process them unencoded. +/// +/// Encodes all characters except ASCII letters, digits, and `_.-~`. In other +/// words, encodes all characters which are not in the unreserved set, +/// as specified by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.3). +/// +/// ```none,ignore +/// Page +/// ``` +/// +/// If you want to preserve `/`, see [`urlencode`](./fn.urlencode.html). +#[inline] +pub fn urlencode_strict(s: T) -> Result>, Infallible> { + Ok(HtmlSafeOutput(UrlencodeFilter(s, URLENCODE_STRICT_SET))) +} + +pub struct UrlencodeFilter(pub T, pub &'static AsciiSet); + +impl fmt::Display for UrlencodeFilter { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(UrlencodeWriter(f, self.1), "{}", self.0) + } +} + +impl FastWritable for UrlencodeFilter { + #[inline] + fn write_into(&self, f: &mut W) -> fmt::Result { + self.0.write_into(&mut UrlencodeWriter(f, self.1)) + } +} + +struct UrlencodeWriter(W, &'static AsciiSet); + +impl fmt::Write for UrlencodeWriter { + #[inline] + fn write_str(&mut self, s: &str) -> fmt::Result { + write!(self.0, "{}", utf8_percent_encode(s, self.1)) + } +} + +#[test] +fn test_urlencoding() { + // Unreserved (https://tools.ietf.org/html/rfc3986.html#section-2.3) + // alpha / digit + assert_eq!(urlencode("AZaz09").unwrap().to_string(), "AZaz09"); + assert_eq!(urlencode_strict("AZaz09").unwrap().to_string(), "AZaz09"); + // other + assert_eq!(urlencode("_.-~").unwrap().to_string(), "_.-~"); + assert_eq!(urlencode_strict("_.-~").unwrap().to_string(), "_.-~"); + + // Reserved (https://tools.ietf.org/html/rfc3986.html#section-2.2) + // gen-delims + assert_eq!( + urlencode(":/?#[]@").unwrap().to_string(), + "%3A/%3F%23%5B%5D%40" + ); + assert_eq!( + urlencode_strict(":/?#[]@").unwrap().to_string(), + "%3A%2F%3F%23%5B%5D%40" + ); + // sub-delims + assert_eq!( + urlencode("!$&'()*+,;=").unwrap().to_string(), + "%21%24%26%27%28%29%2A%2B%2C%3B%3D" + ); + assert_eq!( + urlencode_strict("!$&'()*+,;=").unwrap().to_string(), + "%21%24%26%27%28%29%2A%2B%2C%3B%3D" + ); + + // Other + assert_eq!( + urlencode("žŠďŤňĚáÉóŮ").unwrap().to_string(), + "%C5%BE%C5%A0%C4%8F%C5%A4%C5%88%C4%9A%C3%A1%C3%89%C3%B3%C5%AE" + ); + assert_eq!( + urlencode_strict("žŠďŤňĚáÉóŮ").unwrap().to_string(), + "%C5%BE%C5%A0%C4%8F%C5%A4%C5%88%C4%9A%C3%A1%C3%89%C3%B3%C5%AE" + ); + + // Ferris + assert_eq!(urlencode("🦀").unwrap().to_string(), "%F0%9F%A6%80"); + assert_eq!(urlencode_strict("🦀").unwrap().to_string(), "%F0%9F%A6%80"); +} diff --git a/rinja_derive/src/generator.rs b/rinja_derive/src/generator.rs index db6c54f5..7e12d90e 100644 --- a/rinja_derive/src/generator.rs +++ b/rinja_derive/src/generator.rs @@ -1555,6 +1555,9 @@ impl<'a> Generator<'a> { "pluralize" => return self._visit_pluralize_filter(ctx, buf, args, filter), "ref" => return self._visit_ref_filter(ctx, buf, args, filter), "safe" => return self._visit_safe_filter(ctx, buf, args, filter), + "uppercase" | "urlencode_strict" => { + return self._visit_urlencode(ctx, buf, name, args, filter); + } _ => {} } @@ -1568,6 +1571,30 @@ impl<'a> Generator<'a> { Ok(DisplayWrap::Unwrapped) } + fn _visit_urlencode( + &mut self, + ctx: &Context<'_>, + buf: &mut Buffer, + name: &str, + args: &[WithSpan<'_, Expr<'_>>], + node: &WithSpan<'_, T>, + ) -> Result { + if cfg!(not(feature = "urlencode")) { + return Err(ctx.generate_error( + &format!("the `{name}` filter requires the `urlencode` feature to be enabled"), + node, + )); + } + + // Both filters return HTML-safe strings. + buf.write(format_args!( + "{CRATE}::filters::HtmlSafeOutput({CRATE}::filters::{name}(", + )); + self._visit_args(ctx, buf, args)?; + buf.write(")?)"); + Ok(DisplayWrap::Unwrapped) + } + fn _visit_humansize( &mut self, ctx: &Context<'_>, diff --git a/rinja_derive/src/lib.rs b/rinja_derive/src/lib.rs index f841e603..9a15ae7f 100644 --- a/rinja_derive/src/lib.rs +++ b/rinja_derive/src/lib.rs @@ -391,8 +391,6 @@ const BUILT_IN_FILTERS: &[&str] = &[ "trim", "truncate", "upper", - "uppercase", - "urlencode_strict", "urlencode", "wordcount", ]; From 0c9add9128c811f406492bc557b17020d9b5ea83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Tue, 24 Sep 2024 01:42:32 +0200 Subject: [PATCH 5/9] derive: unify filter generation --- rinja_derive/src/generator.rs | 62 ++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/rinja_derive/src/generator.rs b/rinja_derive/src/generator.rs index 7e12d90e..40ca9d07 100644 --- a/rinja_derive/src/generator.rs +++ b/rinja_derive/src/generator.rs @@ -1538,34 +1538,50 @@ impl<'a> Generator<'a> { ) -> Result { match name { "abs" | "into_f64" | "into_isize" => { - return self._visit_num_traits(ctx, buf, name, args, filter); - } - "deref" => return self._visit_deref_filter(ctx, buf, args, filter), - "escape" | "e" => return self._visit_escape_filter(ctx, buf, args, filter), - "filesizeformat" => { - return self._visit_humansize(ctx, buf, name, args, filter); - } - "fmt" => return self._visit_fmt_filter(ctx, buf, args, filter), - "format" => return self._visit_format_filter(ctx, buf, args, filter), - "join" => return self._visit_join_filter(ctx, buf, args), - "json" | "tojson" => return self._visit_json_filter(ctx, buf, args, filter), + self._visit_num_traits(ctx, buf, name, args, filter) + } + "deref" => self._visit_deref_filter(ctx, buf, args, filter), + "escape" | "e" => self._visit_escape_filter(ctx, buf, args, filter), + "filesizeformat" => self._visit_humansize(ctx, buf, name, args, filter), + "fmt" => self._visit_fmt_filter(ctx, buf, args, filter), + "format" => self._visit_format_filter(ctx, buf, args, filter), + "join" => self._visit_join_filter(ctx, buf, args), + "json" | "tojson" => self._visit_json_filter(ctx, buf, args, filter), "linebreaks" | "linebreaksbr" | "paragraphbreaks" => { - return self._visit_linebreaks_filter(ctx, buf, name, args, filter); + self._visit_linebreaks_filter(ctx, buf, name, args, filter) } - "pluralize" => return self._visit_pluralize_filter(ctx, buf, args, filter), - "ref" => return self._visit_ref_filter(ctx, buf, args, filter), - "safe" => return self._visit_safe_filter(ctx, buf, args, filter), - "uppercase" | "urlencode_strict" => { - return self._visit_urlencode(ctx, buf, name, args, filter); + "pluralize" => self._visit_pluralize_filter(ctx, buf, args, filter), + "ref" => self._visit_ref_filter(ctx, buf, args, filter), + "safe" => self._visit_safe_filter(ctx, buf, args, filter), + "uppercase" | "urlencode_strict" => self._visit_urlencode(ctx, buf, name, args, filter), + name if crate::BUILT_IN_FILTERS.contains(&name) => { + self._visit_builtin_filter(ctx, buf, name, args) } - _ => {} + name => self._visit_custom_filter(ctx, buf, name, args), } + } - if crate::BUILT_IN_FILTERS.contains(&name) { - buf.write(format_args!("{CRATE}::filters::{name}(")); - } else { - buf.write(format_args!("filters::{name}(")); - } + fn _visit_custom_filter( + &mut self, + ctx: &Context<'_>, + buf: &mut Buffer, + name: &str, + args: &[WithSpan<'_, Expr<'_>>], + ) -> Result { + buf.write(format_args!("filters::{name}(")); + self._visit_args(ctx, buf, args)?; + buf.write(")?"); + Ok(DisplayWrap::Unwrapped) + } + + fn _visit_builtin_filter( + &mut self, + ctx: &Context<'_>, + buf: &mut Buffer, + name: &str, + args: &[WithSpan<'_, Expr<'_>>], + ) -> Result { + buf.write(format_args!("{CRATE}::filters::{name}(")); self._visit_args(ctx, buf, args)?; buf.write(")?"); Ok(DisplayWrap::Unwrapped) From 8256eadf5a2bba637e9eacf3ffda8cdaffbf8d05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Tue, 24 Sep 2024 01:48:55 +0200 Subject: [PATCH 6/9] derive: unify filter generation further --- rinja_derive/src/generator.rs | 63 +++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/rinja_derive/src/generator.rs b/rinja_derive/src/generator.rs index 40ca9d07..f632b4fd 100644 --- a/rinja_derive/src/generator.rs +++ b/rinja_derive/src/generator.rs @@ -20,7 +20,7 @@ use crate::config::WhitespaceHandling; use crate::heritage::{Context, Heritage}; use crate::html::write_escaped_str; use crate::input::{Source, TemplateInput}; -use crate::{CompileError, FileInfo, MsgValidEscapers, CRATE}; +use crate::{CompileError, FileInfo, MsgValidEscapers, BUILT_IN_FILTERS, CRATE}; #[derive(Clone, Copy, PartialEq, Debug)] enum EvaluatedResult { @@ -1534,39 +1534,35 @@ impl<'a> Generator<'a> { buf: &mut Buffer, name: &str, args: &[WithSpan<'_, Expr<'_>>], - filter: &WithSpan<'_, T>, + node: &WithSpan<'_, T>, ) -> Result { - match name { - "abs" | "into_f64" | "into_isize" => { - self._visit_num_traits(ctx, buf, name, args, filter) - } - "deref" => self._visit_deref_filter(ctx, buf, args, filter), - "escape" | "e" => self._visit_escape_filter(ctx, buf, args, filter), - "filesizeformat" => self._visit_humansize(ctx, buf, name, args, filter), - "fmt" => self._visit_fmt_filter(ctx, buf, args, filter), - "format" => self._visit_format_filter(ctx, buf, args, filter), - "join" => self._visit_join_filter(ctx, buf, args), - "json" | "tojson" => self._visit_json_filter(ctx, buf, args, filter), - "linebreaks" | "linebreaksbr" | "paragraphbreaks" => { - self._visit_linebreaks_filter(ctx, buf, name, args, filter) - } - "pluralize" => self._visit_pluralize_filter(ctx, buf, args, filter), - "ref" => self._visit_ref_filter(ctx, buf, args, filter), - "safe" => self._visit_safe_filter(ctx, buf, args, filter), - "uppercase" | "urlencode_strict" => self._visit_urlencode(ctx, buf, name, args, filter), - name if crate::BUILT_IN_FILTERS.contains(&name) => { - self._visit_builtin_filter(ctx, buf, name, args) - } - name => self._visit_custom_filter(ctx, buf, name, args), - } + let filter = match name { + "abs" | "into_f64" | "into_isize" => Self::_visit_num_traits, + "deref" => Self::_visit_deref_filter, + "escape" | "e" => Self::_visit_escape_filter, + "filesizeformat" => Self::_visit_humansize, + "fmt" => Self::_visit_fmt_filter, + "format" => Self::_visit_format_filter, + "join" => Self::_visit_join_filter, + "json" | "tojson" => Self::_visit_json_filter, + "linebreaks" | "linebreaksbr" | "paragraphbreaks" => Self::_visit_linebreaks_filter, + "pluralize" => Self::_visit_pluralize_filter, + "ref" => Self::_visit_ref_filter, + "safe" => Self::_visit_safe_filter, + "uppercase" | "urlencode_strict" => Self::_visit_urlencode, + name if BUILT_IN_FILTERS.contains(&name) => Self::_visit_builtin_filter, + _ => Self::_visit_custom_filter, + }; + filter(self, ctx, buf, name, args, node) } - fn _visit_custom_filter( + fn _visit_custom_filter( &mut self, ctx: &Context<'_>, buf: &mut Buffer, name: &str, args: &[WithSpan<'_, Expr<'_>>], + _node: &WithSpan<'_, T>, ) -> Result { buf.write(format_args!("filters::{name}(")); self._visit_args(ctx, buf, args)?; @@ -1574,12 +1570,13 @@ impl<'a> Generator<'a> { Ok(DisplayWrap::Unwrapped) } - fn _visit_builtin_filter( + fn _visit_builtin_filter( &mut self, ctx: &Context<'_>, buf: &mut Buffer, name: &str, args: &[WithSpan<'_, Expr<'_>>], + _node: &WithSpan<'_, T>, ) -> Result { buf.write(format_args!("{CRATE}::filters::{name}(")); self._visit_args(ctx, buf, args)?; @@ -1663,6 +1660,7 @@ impl<'a> Generator<'a> { &mut self, ctx: &Context<'_>, buf: &mut Buffer, + _name: &str, args: &[WithSpan<'_, Expr<'_>>], node: &WithSpan<'_, T>, ) -> Result { @@ -1735,6 +1733,7 @@ impl<'a> Generator<'a> { &mut self, ctx: &Context<'_>, buf: &mut Buffer, + _name: &str, args: &[WithSpan<'_, Expr<'_>>], node: &WithSpan<'_, T>, ) -> Result { @@ -1751,6 +1750,7 @@ impl<'a> Generator<'a> { &mut self, ctx: &Context<'_>, buf: &mut Buffer, + _name: &str, args: &[WithSpan<'_, Expr<'_>>], node: &WithSpan<'_, T>, ) -> Result { @@ -1767,6 +1767,7 @@ impl<'a> Generator<'a> { &mut self, ctx: &Context<'_>, buf: &mut Buffer, + _name: &str, args: &[WithSpan<'_, Expr<'_>>], node: &WithSpan<'_, T>, ) -> Result { @@ -1793,6 +1794,7 @@ impl<'a> Generator<'a> { &mut self, ctx: &Context<'_>, buf: &mut Buffer, + _name: &str, args: &[WithSpan<'_, Expr<'_>>], node: &WithSpan<'_, T>, ) -> Result { @@ -1809,6 +1811,7 @@ impl<'a> Generator<'a> { &mut self, ctx: &Context<'_>, buf: &mut Buffer, + _name: &str, args: &[WithSpan<'_, Expr<'_>>], node: &WithSpan<'_, T>, ) -> Result { @@ -1869,6 +1872,7 @@ impl<'a> Generator<'a> { &mut self, ctx: &Context<'_>, buf: &mut Buffer, + _name: &str, args: &[WithSpan<'_, Expr<'_>>], node: &WithSpan<'_, T>, ) -> Result { @@ -1891,6 +1895,7 @@ impl<'a> Generator<'a> { &mut self, ctx: &Context<'_>, buf: &mut Buffer, + _name: &str, args: &[WithSpan<'_, Expr<'_>>], node: &WithSpan<'_, T>, ) -> Result { @@ -1908,11 +1913,13 @@ impl<'a> Generator<'a> { } // Force type coercion on first argument to `join` filter (see #39). - fn _visit_join_filter( + fn _visit_join_filter( &mut self, ctx: &Context<'_>, buf: &mut Buffer, + _name: &str, args: &[WithSpan<'_, Expr<'_>>], + _node: &WithSpan<'_, T>, ) -> Result { buf.write(CRATE); buf.write("::filters::join((&"); From 4b4418980909122bcbd187f093934a8a699af3e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Tue, 24 Sep 2024 02:04:20 +0200 Subject: [PATCH 7/9] ci: update formatting for edition=2024 --- .rustfmt.toml | 2 +- rinja/benches/escape.rs | 4 +- rinja/benches/to-json.rs | 2 +- rinja/src/filters/humansize.rs | 2 +- rinja/src/filters/json.rs | 2 +- rinja/src/filters/mod.rs | 10 +- rinja/src/filters/num_traits.rs | 2 +- rinja/src/filters/urlencode.rs | 2 +- rinja/src/helpers.rs | 13 +-- rinja_actix/src/lib.rs | 2 +- rinja_axum/tests/basic.rs | 2 +- rinja_derive/src/config.rs | 31 +++--- rinja_derive/src/generator.rs | 2 +- rinja_derive/src/lib.rs | 4 +- .../benches/derive-template.rs | 2 +- rinja_parser/benches/from_str.rs | 2 +- rinja_parser/src/expr.rs | 4 +- rinja_parser/src/lib.rs | 55 ++++------- rinja_parser/src/node.rs | 19 ++-- rinja_parser/src/target.rs | 4 +- rinja_parser/src/tests.rs | 95 +++++++------------ testing/benches/all.rs | 2 +- testing/benches/normalize_identifier.rs | 2 +- 23 files changed, 108 insertions(+), 157 deletions(-) diff --git a/.rustfmt.toml b/.rustfmt.toml index 2702b857..5025fa31 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -5,7 +5,7 @@ newline_style = "Unix" normalize_comments = true unstable_features = true use_field_init_shorthand = true -version = "Two" +style_edition = "2024" ignore = [ "testing/tests/hello.rs", diff --git a/rinja/benches/escape.rs b/rinja/benches/escape.rs index 18125939..74d73f5a 100644 --- a/rinja/benches/escape.rs +++ b/rinja/benches/escape.rs @@ -1,5 +1,5 @@ -use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use rinja::filters::{escape, Html}; +use criterion::{Criterion, black_box, criterion_group, criterion_main}; +use rinja::filters::{Html, escape}; criterion_main!(benches); criterion_group!(benches, functions); diff --git a/rinja/benches/to-json.rs b/rinja/benches/to-json.rs index 8d83a149..9d805ac6 100644 --- a/rinja/benches/to-json.rs +++ b/rinja/benches/to-json.rs @@ -1,4 +1,4 @@ -use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use criterion::{Criterion, black_box, criterion_group, criterion_main}; use rinja::Template; criterion_main!(benches); diff --git a/rinja/src/filters/humansize.rs b/rinja/src/filters/humansize.rs index bbec1c8b..587cd44e 100644 --- a/rinja/src/filters/humansize.rs +++ b/rinja/src/filters/humansize.rs @@ -1,7 +1,7 @@ use std::convert::Infallible; use std::fmt; -use humansize::{ISizeFormatter, ToF64, DECIMAL}; +use humansize::{DECIMAL, ISizeFormatter, ToF64}; /// Returns adequate string representation (in KB, ..) of number of bytes /// diff --git a/rinja/src/filters/json.rs b/rinja/src/filters/json.rs index debada2e..df421743 100644 --- a/rinja/src/filters/json.rs +++ b/rinja/src/filters/json.rs @@ -2,7 +2,7 @@ use std::convert::Infallible; use std::{fmt, io, str}; use serde::Serialize; -use serde_json::ser::{to_writer, PrettyFormatter, Serializer}; +use serde_json::ser::{PrettyFormatter, Serializer, to_writer}; use super::FastWritable; diff --git a/rinja/src/filters/mod.rs b/rinja/src/filters/mod.rs index b0a93564..6299727f 100644 --- a/rinja/src/filters/mod.rs +++ b/rinja/src/filters/mod.rs @@ -22,17 +22,17 @@ mod num_traits; mod urlencode; pub use builtin::{ - capitalize, center, fmt, format, indent, join, linebreaks, linebreaksbr, lower, lowercase, - paragraphbreaks, pluralize, title, trim, truncate, upper, uppercase, wordcount, PluralizeCount, + PluralizeCount, capitalize, center, fmt, format, indent, join, linebreaks, linebreaksbr, lower, + lowercase, paragraphbreaks, pluralize, title, trim, truncate, upper, uppercase, wordcount, }; pub use escape::{ - e, escape, safe, AutoEscape, AutoEscaper, Escaper, FastWritable, Html, HtmlSafe, - HtmlSafeOutput, MaybeSafe, Safe, Text, Unsafe, Writable, WriteWritable, + AutoEscape, AutoEscaper, Escaper, FastWritable, Html, HtmlSafe, HtmlSafeOutput, MaybeSafe, + Safe, Text, Unsafe, Writable, WriteWritable, e, escape, safe, }; #[cfg(feature = "humansize")] pub use humansize::filesizeformat; #[cfg(feature = "serde_json")] -pub use json::{json, json_pretty, AsIndent}; +pub use json::{AsIndent, json, json_pretty}; #[cfg(feature = "num-traits")] pub use num_traits::{abs, into_f64, into_isize}; #[cfg(feature = "urlencode")] diff --git a/rinja/src/filters/num_traits.rs b/rinja/src/filters/num_traits.rs index f42a7475..557866f1 100644 --- a/rinja/src/filters/num_traits.rs +++ b/rinja/src/filters/num_traits.rs @@ -1,5 +1,5 @@ -use num_traits::cast::NumCast; use num_traits::Signed; +use num_traits::cast::NumCast; use crate::{Error, Result}; diff --git a/rinja/src/filters/urlencode.rs b/rinja/src/filters/urlencode.rs index 10acdce4..71d17d0b 100644 --- a/rinja/src/filters/urlencode.rs +++ b/rinja/src/filters/urlencode.rs @@ -2,7 +2,7 @@ use std::convert::Infallible; use std::fmt; use std::fmt::Write; -use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC}; +use percent_encoding::{AsciiSet, NON_ALPHANUMERIC, utf8_percent_encode}; use crate::filters::{FastWritable, HtmlSafeOutput}; diff --git a/rinja/src/helpers.rs b/rinja/src/helpers.rs index 5290a9cd..a06216d3 100644 --- a/rinja/src/helpers.rs +++ b/rinja/src/helpers.rs @@ -34,14 +34,11 @@ where #[inline] fn next(&mut self) -> Option<(::Item, LoopItem)> { self.iter.next().map(|(index, item)| { - ( - item, - LoopItem { - index, - first: index == 0, - last: self.iter.peek().is_none(), - }, - ) + (item, LoopItem { + index, + first: index == 0, + last: self.iter.peek().is_none(), + }) }) } } diff --git a/rinja_actix/src/lib.rs b/rinja_actix/src/lib.rs index f9021a17..29269c9f 100644 --- a/rinja_actix/src/lib.rs +++ b/rinja_actix/src/lib.rs @@ -7,8 +7,8 @@ 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::http::header::HeaderValue; use actix_web::{HttpResponse, HttpResponseBuilder, ResponseError}; #[doc(no_inline)] pub use rinja::*; diff --git a/rinja_axum/tests/basic.rs b/rinja_axum/tests/basic.rs index 1425597d..b5510975 100644 --- a/rinja_axum/tests/basic.rs +++ b/rinja_axum/tests/basic.rs @@ -1,7 +1,7 @@ +use axum::Router; use axum::body::Body; use axum::http::{Request, StatusCode}; use axum::routing::get; -use axum::Router; use http_body_util::BodyExt; use rinja_axum::Template; use tower::util::ServiceExt; diff --git a/rinja_derive/src/config.rs b/rinja_derive/src/config.rs index 3777b0a8..91b62911 100644 --- a/rinja_derive/src/config.rs +++ b/rinja_derive/src/config.rs @@ -14,7 +14,7 @@ use rustc_hash::FxBuildHasher; #[cfg(feature = "config")] use serde::Deserialize; -use crate::{CompileError, FileInfo, CRATE}; +use crate::{CRATE, CompileError, FileInfo}; #[derive(Debug)] pub(crate) struct Config { @@ -682,22 +682,19 @@ mod tests { None, ) .unwrap(); - assert_eq!( - config.escapers, - vec![ - (str_set(&["js"]), "::my_filters::Js".into()), - ( - str_set(&[ - "html", "htm", "j2", "jinja", "jinja2", "rinja", "svg", "xml" - ]), - "::rinja::filters::Html".into() - ), - ( - str_set(&["md", "none", "txt", "yml", ""]), - "::rinja::filters::Text".into() - ), - ] - ); + assert_eq!(config.escapers, vec![ + (str_set(&["js"]), "::my_filters::Js".into()), + ( + str_set(&[ + "html", "htm", "j2", "jinja", "jinja2", "rinja", "svg", "xml" + ]), + "::rinja::filters::Html".into() + ), + ( + str_set(&["md", "none", "txt", "yml", ""]), + "::rinja::filters::Text".into() + ), + ]); } #[cfg(feature = "config")] diff --git a/rinja_derive/src/generator.rs b/rinja_derive/src/generator.rs index f632b4fd..49cd7b8c 100644 --- a/rinja_derive/src/generator.rs +++ b/rinja_derive/src/generator.rs @@ -20,7 +20,7 @@ use crate::config::WhitespaceHandling; use crate::heritage::{Context, Heritage}; use crate::html::write_escaped_str; use crate::input::{Source, TemplateInput}; -use crate::{CompileError, FileInfo, MsgValidEscapers, BUILT_IN_FILTERS, CRATE}; +use crate::{BUILT_IN_FILTERS, CRATE, CompileError, FileInfo, MsgValidEscapers}; #[derive(Clone, Copy, PartialEq, Debug)] enum EvaluatedResult { diff --git a/rinja_derive/src/lib.rs b/rinja_derive/src/lib.rs index 9a15ae7f..9eb6d89f 100644 --- a/rinja_derive/src/lib.rs +++ b/rinja_derive/src/lib.rs @@ -15,11 +15,11 @@ use std::collections::HashMap; use std::fmt; use std::path::Path; -use config::{read_config_file, Config}; +use config::{Config, read_config_file}; use generator::{Generator, MapChain}; use heritage::{Context, Heritage}; use input::{Print, TemplateArgs, TemplateInput}; -use parser::{strip_common, Parsed, WithSpan}; +use parser::{Parsed, WithSpan, strip_common}; #[cfg(not(feature = "__standalone"))] use proc_macro::TokenStream as TokenStream12; #[cfg(feature = "__standalone")] diff --git a/rinja_derive_standalone/benches/derive-template.rs b/rinja_derive_standalone/benches/derive-template.rs index a9449add..0c8967b0 100644 --- a/rinja_derive_standalone/benches/derive-template.rs +++ b/rinja_derive_standalone/benches/derive-template.rs @@ -1,4 +1,4 @@ -use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; +use criterion::{BatchSize, Criterion, criterion_group, criterion_main}; use quote::quote; criterion_main!(benches); diff --git a/rinja_parser/benches/from_str.rs b/rinja_parser/benches/from_str.rs index 42a83ebd..ddff3afd 100644 --- a/rinja_parser/benches/from_str.rs +++ b/rinja_parser/benches/from_str.rs @@ -1,4 +1,4 @@ -use criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput}; +use criterion::{Criterion, Throughput, black_box, criterion_group, criterion_main}; use rinja_parser::{Ast, Syntax}; criterion_main!(benches); diff --git a/rinja_parser/src/expr.rs b/rinja_parser/src/expr.rs index 8f0f92a1..aa287fa7 100644 --- a/rinja_parser/src/expr.rs +++ b/rinja_parser/src/expr.rs @@ -11,8 +11,8 @@ use nom::multi::{fold_many0, many0, separated_list0, separated_list1}; use nom::sequence::{pair, preceded, terminated, tuple}; use crate::{ - char_lit, filter, identifier, keyword, not_ws, num_lit, path_or_identifier, str_lit, ws, - CharLit, ErrorContext, Level, Num, ParseResult, PathOrIdentifier, StrLit, WithSpan, + CharLit, ErrorContext, Level, Num, ParseResult, PathOrIdentifier, StrLit, WithSpan, char_lit, + filter, identifier, keyword, not_ws, num_lit, path_or_identifier, str_lit, ws, }; macro_rules! expr_prec_layer { diff --git a/rinja_parser/src/lib.rs b/rinja_parser/src/lib.rs index 78b2d916..30421d66 100644 --- a/rinja_parser/src/lib.rs +++ b/rinja_parser/src/lib.rs @@ -535,13 +535,10 @@ fn char_lit(i: &str) -> Result<(&str, CharLit<'_>), ParseErr<'_>> { let (nb, max_value, err1, err2) = match c { Char::Literal | Char::Escaped => { - return Ok(( - i, - CharLit { - prefix: b_prefix.map(|_| CharPrefix::Binary), - content: s, - }, - )); + return Ok((i, CharLit { + prefix: b_prefix.map(|_| CharPrefix::Binary), + content: s, + })); } Char::AsciiEscape(nb) => ( nb, @@ -566,13 +563,10 @@ fn char_lit(i: &str) -> Result<(&str, CharLit<'_>), ParseErr<'_>> { return Err(nom::Err::Failure(ErrorContext::new(err2, start))); } - Ok(( - i, - CharLit { - prefix: b_prefix.map(|_| CharPrefix::Binary), - content: s, - }, - )) + Ok((i, CharLit { + prefix: b_prefix.map(|_| CharPrefix::Binary), + content: s, + })) } /// Represents the different kinds of char declarations: @@ -1161,13 +1155,10 @@ mod test { // Check with `b` prefix. assert_eq!( char_lit("b'a'").unwrap(), - ( - "", - crate::CharLit { - prefix: Some(crate::CharPrefix::Binary), - content: "a" - } - ) + ("", crate::CharLit { + prefix: Some(crate::CharPrefix::Binary), + content: "a" + }) ); // Should fail. @@ -1185,23 +1176,17 @@ mod test { fn test_str_lit() { assert_eq!( str_lit(r#"b"hello""#).unwrap(), - ( - "", - StrLit { - prefix: Some(StrPrefix::Binary), - content: "hello" - } - ) + ("", StrLit { + prefix: Some(StrPrefix::Binary), + content: "hello" + }) ); assert_eq!( str_lit(r#"c"hello""#).unwrap(), - ( - "", - StrLit { - prefix: Some(StrPrefix::CLike), - content: "hello" - } - ) + ("", StrLit { + prefix: Some(StrPrefix::CLike), + content: "hello" + }) ); assert!(str_lit(r#"d"hello""#).is_err()); } diff --git a/rinja_parser/src/node.rs b/rinja_parser/src/node.rs index 0056a23d..b4b652b1 100644 --- a/rinja_parser/src/node.rs +++ b/rinja_parser/src/node.rs @@ -11,8 +11,8 @@ use nom::sequence::{delimited, pair, preceded, tuple}; use crate::memchr_splitter::{Splitter1, Splitter2, Splitter3}; use crate::{ - filter, identifier, is_ws, keyword, not_ws, skip_till, str_lit_without_prefix, ws, - ErrorContext, Expr, Filter, ParseResult, State, Target, WithSpan, + ErrorContext, Expr, Filter, ParseResult, State, Target, WithSpan, filter, identifier, is_ws, + keyword, not_ws, skip_till, str_lit_without_prefix, ws, }; #[derive(Debug, PartialEq)] @@ -409,14 +409,11 @@ impl<'a> CondTest<'a> { ws(|i| Expr::parse(i, s.level.get())), )(i)?; let contains_bool_lit_or_is_defined = expr.contains_bool_lit_or_is_defined(); - Ok(( - i, - Self { - target, - expr, - contains_bool_lit_or_is_defined, - }, - )) + Ok((i, Self { + target, + expr, + contains_bool_lit_or_is_defined, + })) } } @@ -1414,7 +1411,7 @@ fn is_rust_keyword(ident: &str) -> bool { #[cfg(test)] mod kws_tests { - use super::{is_rust_keyword, KWS, KWS_EXTRA, MAX_REPL_LEN}; + use super::{KWS, KWS_EXTRA, MAX_REPL_LEN, is_rust_keyword}; fn ensure_utf8_inner(entry: &[&[[u8; MAX_REPL_LEN]]]) { for kws in entry { diff --git a/rinja_parser/src/target.rs b/rinja_parser/src/target.rs index 46372c2f..cf6298b1 100644 --- a/rinja_parser/src/target.rs +++ b/rinja_parser/src/target.rs @@ -6,8 +6,8 @@ use nom::multi::separated_list1; use nom::sequence::{pair, preceded, tuple}; use crate::{ - bool_lit, char_lit, identifier, keyword, num_lit, path_or_identifier, str_lit, ws, CharLit, - ErrorContext, Num, ParseErr, ParseResult, PathOrIdentifier, State, StrLit, WithSpan, + CharLit, ErrorContext, Num, ParseErr, ParseResult, PathOrIdentifier, State, StrLit, WithSpan, + bool_lit, char_lit, identifier, keyword, num_lit, path_or_identifier, str_lit, ws, }; #[derive(Clone, Debug, PartialEq)] diff --git a/rinja_parser/src/tests.rs b/rinja_parser/src/tests.rs index c3f37e25..468756c3 100644 --- a/rinja_parser/src/tests.rs +++ b/rinja_parser/src/tests.rs @@ -112,13 +112,9 @@ fn test_parse_numbers() { fn test_parse_var() { let s = Syntax::default(); - assert_eq!( - Ast::from_str("{{ foo }}", None, &s).unwrap().nodes, - vec![Node::Expr( - Ws(None, None), - WithSpan::no_span(Expr::Var("foo")) - )], - ); + assert_eq!(Ast::from_str("{{ foo }}", None, &s).unwrap().nodes, vec![ + Node::Expr(Ws(None, None), WithSpan::no_span(Expr::Var("foo"))) + ],); assert_eq!( Ast::from_str("{{ foo_bar }}", None, &s).unwrap().nodes, vec![Node::Expr( @@ -127,26 +123,18 @@ fn test_parse_var() { )], ); - assert_eq!( - Ast::from_str("{{ none }}", None, &s).unwrap().nodes, - vec![Node::Expr( - Ws(None, None), - WithSpan::no_span(Expr::Var("none")) - )], - ); + assert_eq!(Ast::from_str("{{ none }}", None, &s).unwrap().nodes, vec![ + Node::Expr(Ws(None, None), WithSpan::no_span(Expr::Var("none"))) + ],); } #[test] fn test_parse_const() { let s = Syntax::default(); - assert_eq!( - Ast::from_str("{{ FOO }}", None, &s).unwrap().nodes, - vec![Node::Expr( - Ws(None, None), - WithSpan::no_span(Expr::Path(vec!["FOO"])) - )], - ); + assert_eq!(Ast::from_str("{{ FOO }}", None, &s).unwrap().nodes, vec![ + Node::Expr(Ws(None, None), WithSpan::no_span(Expr::Path(vec!["FOO"]))) + ],); assert_eq!( Ast::from_str("{{ FOO_BAR }}", None, &s).unwrap().nodes, vec![Node::Expr( @@ -155,26 +143,18 @@ fn test_parse_const() { )], ); - assert_eq!( - Ast::from_str("{{ NONE }}", None, &s).unwrap().nodes, - vec![Node::Expr( - Ws(None, None), - WithSpan::no_span(Expr::Path(vec!["NONE"])) - )], - ); + assert_eq!(Ast::from_str("{{ NONE }}", None, &s).unwrap().nodes, vec![ + Node::Expr(Ws(None, None), WithSpan::no_span(Expr::Path(vec!["NONE"]))) + ],); } #[test] fn test_parse_path() { let s = Syntax::default(); - assert_eq!( - Ast::from_str("{{ None }}", None, &s).unwrap().nodes, - vec![Node::Expr( - Ws(None, None), - WithSpan::no_span(Expr::Path(vec!["None"])) - )], - ); + assert_eq!(Ast::from_str("{{ None }}", None, &s).unwrap().nodes, vec![ + Node::Expr(Ws(None, None), WithSpan::no_span(Expr::Path(vec!["None"]))) + ],); assert_eq!( Ast::from_str("{{ Some(123) }}", None, &s).unwrap().nodes, vec![Node::Expr( @@ -328,41 +308,36 @@ fn test_rust_macro() { WithSpan::no_span(Expr::RustMacro(vec!["alloc", "vec"], "1, 2, 3")), )], ); - assert_eq!( - Ast::from_str("{{a!()}}", None, &syntax).unwrap().nodes, - [Node::Expr( + assert_eq!(Ast::from_str("{{a!()}}", None, &syntax).unwrap().nodes, [ + Node::Expr( Ws(None, None), WithSpan::no_span(Expr::RustMacro(vec!["a"], "")) - )], - ); - assert_eq!( - Ast::from_str("{{a !()}}", None, &syntax).unwrap().nodes, - [Node::Expr( + ) + ],); + assert_eq!(Ast::from_str("{{a !()}}", None, &syntax).unwrap().nodes, [ + Node::Expr( Ws(None, None), WithSpan::no_span(Expr::RustMacro(vec!["a"], "")) - )], - ); - assert_eq!( - Ast::from_str("{{a! ()}}", None, &syntax).unwrap().nodes, - [Node::Expr( + ) + ],); + assert_eq!(Ast::from_str("{{a! ()}}", None, &syntax).unwrap().nodes, [ + Node::Expr( Ws(None, None), WithSpan::no_span(Expr::RustMacro(vec!["a"], "")) - )], - ); - assert_eq!( - Ast::from_str("{{a ! ()}}", None, &syntax).unwrap().nodes, - [Node::Expr( + ) + ],); + assert_eq!(Ast::from_str("{{a ! ()}}", None, &syntax).unwrap().nodes, [ + Node::Expr( Ws(None, None), WithSpan::no_span(Expr::RustMacro(vec!["a"], "")) - )], - ); - assert_eq!( - Ast::from_str("{{A!()}}", None, &syntax).unwrap().nodes, - [Node::Expr( + ) + ],); + assert_eq!(Ast::from_str("{{A!()}}", None, &syntax).unwrap().nodes, [ + Node::Expr( Ws(None, None), WithSpan::no_span(Expr::RustMacro(vec!["A"], "")) - )], - ); + ) + ],); assert_eq!( &*Ast::from_str("{{a.b.c!( hello )}}", None, &syntax) .unwrap_err() diff --git a/testing/benches/all.rs b/testing/benches/all.rs index 6cbfd18c..314ba716 100644 --- a/testing/benches/all.rs +++ b/testing/benches/all.rs @@ -1,7 +1,7 @@ use std::hint::black_box; use std::iter::repeat; -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::{Criterion, criterion_group, criterion_main}; use rinja::Template; criterion_main!(benches); diff --git a/testing/benches/normalize_identifier.rs b/testing/benches/normalize_identifier.rs index 1005ebcd..1488a9e5 100644 --- a/testing/benches/normalize_identifier.rs +++ b/testing/benches/normalize_identifier.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use std::iter::FusedIterator; -use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use criterion::{Criterion, black_box, criterion_group, criterion_main}; criterion_main!(benches); criterion_group!(benches, functions); From 0d8cda38b769e0bec3607eb9c5959f23e2e68fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Tue, 24 Sep 2024 02:17:01 +0200 Subject: [PATCH 8/9] ci: make sure all settings apply to subprojects, too --- examples/actix-web-app/.rustfmt.toml | 1 + examples/actix-web-app/Cargo.toml | 12 ++++++------ examples/actix-web-app/_typos.toml | 1 + examples/actix-web-app/deny.toml | 1 + examples/actix-web-app/src/main.rs | 4 ++-- examples/actix-web-app/tomlfmt.toml | 1 + fuzzing/.rustfmt.toml | 1 + fuzzing/_typos.toml | 1 + fuzzing/deny.toml | 1 + fuzzing/tomlfmt.toml | 1 + rinja_actix/.rustfmt.toml | 1 + rinja_actix/Cargo.toml | 24 ++++++++++++------------ rinja_actix/_typos.toml | 1 + rinja_actix/deny.toml | 1 + rinja_actix/tomlfmt.toml | 1 + rinja_axum/.rustfmt.toml | 1 + rinja_axum/Cargo.toml | 24 ++++++++++++------------ rinja_axum/_typos.toml | 1 + rinja_axum/deny.toml | 1 + rinja_axum/tomlfmt.toml | 1 + rinja_derive_standalone/.rustfmt.toml | 1 + rinja_derive_standalone/Cargo.toml | 6 +++--- rinja_derive_standalone/_typos.toml | 1 + rinja_derive_standalone/deny.toml | 1 + rinja_derive_standalone/tomlfmt.toml | 1 + rinja_parser/.rustfmt.toml | 1 + rinja_parser/_typos.toml | 1 + rinja_parser/deny.toml | 1 + rinja_parser/tomlfmt.toml | 1 + rinja_rocket/.rustfmt.toml | 1 + rinja_rocket/Cargo.toml | 20 ++++++++++---------- rinja_rocket/_typos.toml | 1 + rinja_rocket/deny.toml | 1 + rinja_rocket/tomlfmt.toml | 1 + rinja_warp/.rustfmt.toml | 1 + rinja_warp/Cargo.toml | 20 ++++++++++---------- rinja_warp/_typos.toml | 1 + rinja_warp/deny.toml | 1 + rinja_warp/tomlfmt.toml | 1 + 39 files changed, 87 insertions(+), 55 deletions(-) create mode 120000 examples/actix-web-app/.rustfmt.toml create mode 120000 examples/actix-web-app/_typos.toml create mode 120000 examples/actix-web-app/deny.toml create mode 120000 examples/actix-web-app/tomlfmt.toml create mode 120000 fuzzing/.rustfmt.toml create mode 120000 fuzzing/_typos.toml create mode 120000 fuzzing/deny.toml create mode 120000 fuzzing/tomlfmt.toml create mode 120000 rinja_actix/.rustfmt.toml create mode 120000 rinja_actix/_typos.toml create mode 120000 rinja_actix/deny.toml create mode 120000 rinja_actix/tomlfmt.toml create mode 120000 rinja_axum/.rustfmt.toml create mode 120000 rinja_axum/_typos.toml create mode 120000 rinja_axum/deny.toml create mode 120000 rinja_axum/tomlfmt.toml create mode 120000 rinja_derive_standalone/.rustfmt.toml create mode 120000 rinja_derive_standalone/_typos.toml create mode 120000 rinja_derive_standalone/deny.toml create mode 120000 rinja_derive_standalone/tomlfmt.toml create mode 120000 rinja_parser/.rustfmt.toml create mode 120000 rinja_parser/_typos.toml create mode 120000 rinja_parser/deny.toml create mode 120000 rinja_parser/tomlfmt.toml create mode 120000 rinja_rocket/.rustfmt.toml create mode 120000 rinja_rocket/_typos.toml create mode 120000 rinja_rocket/deny.toml create mode 120000 rinja_rocket/tomlfmt.toml create mode 120000 rinja_warp/.rustfmt.toml create mode 120000 rinja_warp/_typos.toml create mode 120000 rinja_warp/deny.toml create mode 120000 rinja_warp/tomlfmt.toml diff --git a/examples/actix-web-app/.rustfmt.toml b/examples/actix-web-app/.rustfmt.toml new file mode 120000 index 00000000..fed79016 --- /dev/null +++ b/examples/actix-web-app/.rustfmt.toml @@ -0,0 +1 @@ +../../.rustfmt.toml \ No newline at end of file diff --git a/examples/actix-web-app/Cargo.toml b/examples/actix-web-app/Cargo.toml index 96d352d1..48219fb7 100644 --- a/examples/actix-web-app/Cargo.toml +++ b/examples/actix-web-app/Cargo.toml @@ -1,3 +1,8 @@ +# In a real application you would not need this section. It is only used in here, so that this +# example can have a more lenient MSRV (minimum supported rust version) than rinja as a whole. +[workspace] +members = ["."] + [package] name = "actix-web-app" version = "0.3.4" @@ -6,12 +11,12 @@ license = "MIT OR Apache-2.0" publish = false [dependencies] +actix-web = { version = "4.8.0", default-features = false, features = ["macros"] } # This is an example application that uses both rinja as template engine, # and actix-web as your web-framework. # rinja_actix makes it easy to use rinja templates as `Responder` of an actix-web request. # The rendered template is simply the response of your handler! rinja_actix = { version = "0.3.4", path = "../../rinja_actix" } -actix-web = { version = "4.8.0", default-features = false, features = ["macros"] } tokio = { version = "1.38.0", features = ["sync", "rt-multi-thread"] } # serde and strum are used to parse (deserialize) and generate (serialize) information @@ -25,8 +30,3 @@ env_logger = "0.11.3" log = "0.4.22" pretty-error-debug = "0.3.0" thiserror = "1.0.61" - -# In a real application you would not need this section. It is only used in here, so that this -# example can have a more lenient MSRV (minimum supported rust version) than rinja as a whole. -[workspace] -members = ["."] diff --git a/examples/actix-web-app/_typos.toml b/examples/actix-web-app/_typos.toml new file mode 120000 index 00000000..15e4306a --- /dev/null +++ b/examples/actix-web-app/_typos.toml @@ -0,0 +1 @@ +../../_typos.toml \ No newline at end of file diff --git a/examples/actix-web-app/deny.toml b/examples/actix-web-app/deny.toml new file mode 120000 index 00000000..ae01e357 --- /dev/null +++ b/examples/actix-web-app/deny.toml @@ -0,0 +1 @@ +../../deny.toml \ No newline at end of file diff --git a/examples/actix-web-app/src/main.rs b/examples/actix-web-app/src/main.rs index 1f9722c1..b4a23248 100644 --- a/examples/actix-web-app/src/main.rs +++ b/examples/actix-web-app/src/main.rs @@ -1,6 +1,6 @@ -use actix_web::http::{header, Method}; +use actix_web::http::{Method, header}; use actix_web::{ - get, middleware, web, App, HttpRequest, HttpResponse, HttpServer, Responder, Result, + App, HttpRequest, HttpResponse, HttpServer, Responder, Result, get, middleware, web, }; use rinja_actix::Template; use serde::Deserialize; diff --git a/examples/actix-web-app/tomlfmt.toml b/examples/actix-web-app/tomlfmt.toml new file mode 120000 index 00000000..f5ea3619 --- /dev/null +++ b/examples/actix-web-app/tomlfmt.toml @@ -0,0 +1 @@ +../../tomlfmt.toml \ No newline at end of file diff --git a/fuzzing/.rustfmt.toml b/fuzzing/.rustfmt.toml new file mode 120000 index 00000000..a7ef950c --- /dev/null +++ b/fuzzing/.rustfmt.toml @@ -0,0 +1 @@ +../.rustfmt.toml \ No newline at end of file diff --git a/fuzzing/_typos.toml b/fuzzing/_typos.toml new file mode 120000 index 00000000..2264b5db --- /dev/null +++ b/fuzzing/_typos.toml @@ -0,0 +1 @@ +../_typos.toml \ No newline at end of file diff --git a/fuzzing/deny.toml b/fuzzing/deny.toml new file mode 120000 index 00000000..a65e17bb --- /dev/null +++ b/fuzzing/deny.toml @@ -0,0 +1 @@ +../deny.toml \ No newline at end of file diff --git a/fuzzing/tomlfmt.toml b/fuzzing/tomlfmt.toml new file mode 120000 index 00000000..053191cc --- /dev/null +++ b/fuzzing/tomlfmt.toml @@ -0,0 +1 @@ +../tomlfmt.toml \ No newline at end of file diff --git a/rinja_actix/.rustfmt.toml b/rinja_actix/.rustfmt.toml new file mode 120000 index 00000000..a7ef950c --- /dev/null +++ b/rinja_actix/.rustfmt.toml @@ -0,0 +1 @@ +../.rustfmt.toml \ No newline at end of file diff --git a/rinja_actix/Cargo.toml b/rinja_actix/Cargo.toml index 6a2e3b28..16b13050 100644 --- a/rinja_actix/Cargo.toml +++ b/rinja_actix/Cargo.toml @@ -1,3 +1,6 @@ +[workspace] +members = ["."] + [package] name = "rinja_actix" version = "0.3.4" @@ -16,16 +19,6 @@ rust-version = "1.71" all-features = true rustdoc-args = ["--generate-link-to-definition", "--cfg=docsrs"] -[dependencies] -rinja = { version = "0.3.4", path = "../rinja", default-features = false, features = ["with-actix-web"] } - -actix-web = { version = "4", default-features = false } - -[dev-dependencies] -actix-rt = { version = "2", default-features = false } -actix-test = "0.1" -bytes = { version = "1" } - [features] default = ["rinja/default"] code-in-doc = ["rinja/code-in-doc"] @@ -35,5 +28,12 @@ num-traits = ["rinja/num-traits"] serde_json = ["rinja/serde_json"] urlencode = ["rinja/urlencode"] -[workspace] -members = ["."] +[dependencies] +rinja = { version = "0.3.4", path = "../rinja", default-features = false, features = ["with-actix-web"] } + +actix-web = { version = "4", default-features = false } + +[dev-dependencies] +actix-rt = { version = "2", default-features = false } +actix-test = "0.1" +bytes = { version = "1" } diff --git a/rinja_actix/_typos.toml b/rinja_actix/_typos.toml new file mode 120000 index 00000000..2264b5db --- /dev/null +++ b/rinja_actix/_typos.toml @@ -0,0 +1 @@ +../_typos.toml \ No newline at end of file diff --git a/rinja_actix/deny.toml b/rinja_actix/deny.toml new file mode 120000 index 00000000..a65e17bb --- /dev/null +++ b/rinja_actix/deny.toml @@ -0,0 +1 @@ +../deny.toml \ No newline at end of file diff --git a/rinja_actix/tomlfmt.toml b/rinja_actix/tomlfmt.toml new file mode 120000 index 00000000..053191cc --- /dev/null +++ b/rinja_actix/tomlfmt.toml @@ -0,0 +1 @@ +../tomlfmt.toml \ No newline at end of file diff --git a/rinja_axum/.rustfmt.toml b/rinja_axum/.rustfmt.toml new file mode 120000 index 00000000..a7ef950c --- /dev/null +++ b/rinja_axum/.rustfmt.toml @@ -0,0 +1 @@ +../.rustfmt.toml \ No newline at end of file diff --git a/rinja_axum/Cargo.toml b/rinja_axum/Cargo.toml index ed1c943e..acc06bd9 100644 --- a/rinja_axum/Cargo.toml +++ b/rinja_axum/Cargo.toml @@ -1,3 +1,6 @@ +[workspace] +members = ["."] + [package] name = "rinja_axum" version = "0.3.4" @@ -16,6 +19,15 @@ readme = "README.md" all-features = true rustdoc-args = ["--generate-link-to-definition", "--cfg=docsrs"] +[features] +default = ["rinja/default"] +code-in-doc = ["rinja/code-in-doc"] +config = ["rinja/config"] +humansize = ["rinja/humansize"] +num-traits = ["rinja/num-traits"] +serde_json = ["rinja/serde_json"] +urlencode = ["rinja/urlencode"] + [dependencies] rinja = { version = "0.3.4", path = "../rinja", default-features = false, features = ["with-axum"] } @@ -27,15 +39,3 @@ axum = { version = "0.7", default-features = false } http-body-util = "0.1" tokio = { version = "1.0", features = ["macros", "rt"] } tower = { version = "0.5", features = ["util"] } - -[features] -default = ["rinja/default"] -code-in-doc = ["rinja/code-in-doc"] -config = ["rinja/config"] -humansize = ["rinja/humansize"] -num-traits = ["rinja/num-traits"] -serde_json = ["rinja/serde_json"] -urlencode = ["rinja/urlencode"] - -[workspace] -members = ["."] diff --git a/rinja_axum/_typos.toml b/rinja_axum/_typos.toml new file mode 120000 index 00000000..2264b5db --- /dev/null +++ b/rinja_axum/_typos.toml @@ -0,0 +1 @@ +../_typos.toml \ No newline at end of file diff --git a/rinja_axum/deny.toml b/rinja_axum/deny.toml new file mode 120000 index 00000000..a65e17bb --- /dev/null +++ b/rinja_axum/deny.toml @@ -0,0 +1 @@ +../deny.toml \ No newline at end of file diff --git a/rinja_axum/tomlfmt.toml b/rinja_axum/tomlfmt.toml new file mode 120000 index 00000000..053191cc --- /dev/null +++ b/rinja_axum/tomlfmt.toml @@ -0,0 +1 @@ +../tomlfmt.toml \ No newline at end of file diff --git a/rinja_derive_standalone/.rustfmt.toml b/rinja_derive_standalone/.rustfmt.toml new file mode 120000 index 00000000..a7ef950c --- /dev/null +++ b/rinja_derive_standalone/.rustfmt.toml @@ -0,0 +1 @@ +../.rustfmt.toml \ No newline at end of file diff --git a/rinja_derive_standalone/Cargo.toml b/rinja_derive_standalone/Cargo.toml index 492394c4..f503b3d8 100644 --- a/rinja_derive_standalone/Cargo.toml +++ b/rinja_derive_standalone/Cargo.toml @@ -1,3 +1,6 @@ +[workspace] +members = ["."] + [package] name = "rinja_derive_standalone" version = "0.3.4" @@ -56,6 +59,3 @@ syn = { version = "2.0.3", features = ["full"] } name = "derive-template" harness = false required-features = ["__standalone"] - -[workspace] -members = ["."] diff --git a/rinja_derive_standalone/_typos.toml b/rinja_derive_standalone/_typos.toml new file mode 120000 index 00000000..2264b5db --- /dev/null +++ b/rinja_derive_standalone/_typos.toml @@ -0,0 +1 @@ +../_typos.toml \ No newline at end of file diff --git a/rinja_derive_standalone/deny.toml b/rinja_derive_standalone/deny.toml new file mode 120000 index 00000000..a65e17bb --- /dev/null +++ b/rinja_derive_standalone/deny.toml @@ -0,0 +1 @@ +../deny.toml \ No newline at end of file diff --git a/rinja_derive_standalone/tomlfmt.toml b/rinja_derive_standalone/tomlfmt.toml new file mode 120000 index 00000000..053191cc --- /dev/null +++ b/rinja_derive_standalone/tomlfmt.toml @@ -0,0 +1 @@ +../tomlfmt.toml \ No newline at end of file diff --git a/rinja_parser/.rustfmt.toml b/rinja_parser/.rustfmt.toml new file mode 120000 index 00000000..a7ef950c --- /dev/null +++ b/rinja_parser/.rustfmt.toml @@ -0,0 +1 @@ +../.rustfmt.toml \ No newline at end of file diff --git a/rinja_parser/_typos.toml b/rinja_parser/_typos.toml new file mode 120000 index 00000000..2264b5db --- /dev/null +++ b/rinja_parser/_typos.toml @@ -0,0 +1 @@ +../_typos.toml \ No newline at end of file diff --git a/rinja_parser/deny.toml b/rinja_parser/deny.toml new file mode 120000 index 00000000..a65e17bb --- /dev/null +++ b/rinja_parser/deny.toml @@ -0,0 +1 @@ +../deny.toml \ No newline at end of file diff --git a/rinja_parser/tomlfmt.toml b/rinja_parser/tomlfmt.toml new file mode 120000 index 00000000..053191cc --- /dev/null +++ b/rinja_parser/tomlfmt.toml @@ -0,0 +1 @@ +../tomlfmt.toml \ No newline at end of file diff --git a/rinja_rocket/.rustfmt.toml b/rinja_rocket/.rustfmt.toml new file mode 120000 index 00000000..a7ef950c --- /dev/null +++ b/rinja_rocket/.rustfmt.toml @@ -0,0 +1 @@ +../.rustfmt.toml \ No newline at end of file diff --git a/rinja_rocket/Cargo.toml b/rinja_rocket/Cargo.toml index abfef9d9..0df44f0e 100644 --- a/rinja_rocket/Cargo.toml +++ b/rinja_rocket/Cargo.toml @@ -1,3 +1,6 @@ +[workspace] +members = ["."] + [package] name = "rinja_rocket" version = "0.3.4" @@ -16,14 +19,6 @@ rust-version = "1.71" all-features = true rustdoc-args = ["--generate-link-to-definition", "--cfg=docsrs"] -[dependencies] -rinja = { version = "0.3.4", path = "../rinja", default-features = false, features = ["with-rocket"] } - -rocket = { version = "0.5", default-features = false } - -[dev-dependencies] -tokio = { version = "1.0", features = ["macros", "rt"] } - [features] default = ["rinja/default"] code-in-doc = ["rinja/code-in-doc"] @@ -33,5 +28,10 @@ num-traits = ["rinja/num-traits"] serde_json = ["rinja/serde_json"] urlencode = ["rinja/urlencode"] -[workspace] -members = ["."] +[dependencies] +rinja = { version = "0.3.4", path = "../rinja", default-features = false, features = ["with-rocket"] } + +rocket = { version = "0.5", default-features = false } + +[dev-dependencies] +tokio = { version = "1.0", features = ["macros", "rt"] } diff --git a/rinja_rocket/_typos.toml b/rinja_rocket/_typos.toml new file mode 120000 index 00000000..2264b5db --- /dev/null +++ b/rinja_rocket/_typos.toml @@ -0,0 +1 @@ +../_typos.toml \ No newline at end of file diff --git a/rinja_rocket/deny.toml b/rinja_rocket/deny.toml new file mode 120000 index 00000000..a65e17bb --- /dev/null +++ b/rinja_rocket/deny.toml @@ -0,0 +1 @@ +../deny.toml \ No newline at end of file diff --git a/rinja_rocket/tomlfmt.toml b/rinja_rocket/tomlfmt.toml new file mode 120000 index 00000000..053191cc --- /dev/null +++ b/rinja_rocket/tomlfmt.toml @@ -0,0 +1 @@ +../tomlfmt.toml \ No newline at end of file diff --git a/rinja_warp/.rustfmt.toml b/rinja_warp/.rustfmt.toml new file mode 120000 index 00000000..a7ef950c --- /dev/null +++ b/rinja_warp/.rustfmt.toml @@ -0,0 +1 @@ +../.rustfmt.toml \ No newline at end of file diff --git a/rinja_warp/Cargo.toml b/rinja_warp/Cargo.toml index 8f944097..2e37d28e 100644 --- a/rinja_warp/Cargo.toml +++ b/rinja_warp/Cargo.toml @@ -1,3 +1,6 @@ +[workspace] +members = ["."] + [package] name = "rinja_warp" version = "0.3.4" @@ -16,14 +19,6 @@ rust-version = "1.71" all-features = true rustdoc-args = ["--generate-link-to-definition", "--cfg=docsrs"] -[dependencies] -rinja = { version = "0.3.4", path = "../rinja", default-features = false, features = ["with-warp"] } - -warp = { version = "0.3", default-features = false } - -[dev-dependencies] -tokio = { version = "1.0", features = ["macros", "rt"] } - [features] default = ["rinja/default"] code-in-doc = ["rinja/code-in-doc"] @@ -33,5 +28,10 @@ num-traits = ["rinja/num-traits"] serde_json = ["rinja/serde_json"] urlencode = ["rinja/urlencode"] -[workspace] -members = ["."] +[dependencies] +rinja = { version = "0.3.4", path = "../rinja", default-features = false, features = ["with-warp"] } + +warp = { version = "0.3", default-features = false } + +[dev-dependencies] +tokio = { version = "1.0", features = ["macros", "rt"] } diff --git a/rinja_warp/_typos.toml b/rinja_warp/_typos.toml new file mode 120000 index 00000000..2264b5db --- /dev/null +++ b/rinja_warp/_typos.toml @@ -0,0 +1 @@ +../_typos.toml \ No newline at end of file diff --git a/rinja_warp/deny.toml b/rinja_warp/deny.toml new file mode 120000 index 00000000..a65e17bb --- /dev/null +++ b/rinja_warp/deny.toml @@ -0,0 +1 @@ +../deny.toml \ No newline at end of file diff --git a/rinja_warp/tomlfmt.toml b/rinja_warp/tomlfmt.toml new file mode 120000 index 00000000..053191cc --- /dev/null +++ b/rinja_warp/tomlfmt.toml @@ -0,0 +1 @@ +../tomlfmt.toml \ No newline at end of file From 80bb96931b1a325d0ce74af032d62b222c39a233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Kijewski?= Date: Tue, 24 Sep 2024 02:23:43 +0200 Subject: [PATCH 9/9] ci: fix warnings in rustc 1.71 --- rinja/src/filters/mod.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rinja/src/filters/mod.rs b/rinja/src/filters/mod.rs index 6299727f..39de84ab 100644 --- a/rinja/src/filters/mod.rs +++ b/rinja/src/filters/mod.rs @@ -21,19 +21,19 @@ mod num_traits; #[cfg(feature = "urlencode")] mod urlencode; -pub use builtin::{ +pub use self::builtin::{ PluralizeCount, capitalize, center, fmt, format, indent, join, linebreaks, linebreaksbr, lower, lowercase, paragraphbreaks, pluralize, title, trim, truncate, upper, uppercase, wordcount, }; -pub use escape::{ +pub use self::escape::{ AutoEscape, AutoEscaper, Escaper, FastWritable, Html, HtmlSafe, HtmlSafeOutput, MaybeSafe, Safe, Text, Unsafe, Writable, WriteWritable, e, escape, safe, }; #[cfg(feature = "humansize")] -pub use humansize::filesizeformat; +pub use self::humansize::filesizeformat; #[cfg(feature = "serde_json")] -pub use json::{AsIndent, json, json_pretty}; +pub use self::json::{AsIndent, json, json_pretty}; #[cfg(feature = "num-traits")] -pub use num_traits::{abs, into_f64, into_isize}; +pub use self::num_traits::{abs, into_f64, into_isize}; #[cfg(feature = "urlencode")] -pub use urlencode::{urlencode, urlencode_strict}; +pub use self::urlencode::{urlencode, urlencode_strict};