summaryrefslogtreecommitdiffstats
path: root/vendor/askama_escape/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/askama_escape/src')
-rw-r--r--vendor/askama_escape/src/lib.rs65
1 files changed, 59 insertions, 6 deletions
diff --git a/vendor/askama_escape/src/lib.rs b/vendor/askama_escape/src/lib.rs
index 4643390ca..178884308 100644
--- a/vendor/askama_escape/src/lib.rs
+++ b/vendor/askama_escape/src/lib.rs
@@ -1,12 +1,11 @@
-#![no_std]
+#![cfg_attr(not(any(feature = "json", test)), no_std)]
#![deny(elided_lifetimes_in_paths)]
-
-#[cfg(test)]
-extern crate std;
+#![deny(unreachable_pub)]
use core::fmt::{self, Display, Formatter, Write};
use core::str;
+#[derive(Debug)]
pub struct MarkupDisplay<E, T>
where
E: Escaper,
@@ -35,6 +34,7 @@ where
}
}
+ #[must_use]
pub fn mark_safe(mut self) -> MarkupDisplay<E, T> {
self.value = match self.value {
DisplayValue::Unsafe(t) => DisplayValue::Safe(t),
@@ -64,12 +64,13 @@ where
}
}
+#[derive(Debug)]
pub struct EscapeWriter<'a, E, W> {
fmt: W,
escaper: &'a E,
}
-impl<'a, E, W> Write for EscapeWriter<'a, E, W>
+impl<E, W> Write for EscapeWriter<'_, E, W>
where
W: Write,
E: Escaper,
@@ -86,6 +87,7 @@ where
Escaped { string, escaper }
}
+#[derive(Debug)]
pub struct Escaped<'a, E>
where
E: Escaper,
@@ -94,7 +96,7 @@ where
escaper: E,
}
-impl<'a, E> Display for Escaped<'a, E>
+impl<E> Display for Escaped<'_, E>
where
E: Escaper,
{
@@ -170,6 +172,57 @@ pub trait Escaper {
const FLAG: u8 = b'>' - b'"';
+/// Escape chevrons, ampersand and apostrophes for use in JSON
+#[cfg(feature = "json")]
+#[derive(Debug, Clone, Default)]
+pub struct JsonEscapeBuffer(Vec<u8>);
+
+#[cfg(feature = "json")]
+impl JsonEscapeBuffer {
+ pub fn new() -> Self {
+ Self(Vec::new())
+ }
+
+ pub fn finish(self) -> String {
+ unsafe { String::from_utf8_unchecked(self.0) }
+ }
+}
+
+#[cfg(feature = "json")]
+impl std::io::Write for JsonEscapeBuffer {
+ fn write(&mut self, bytes: &[u8]) -> std::io::Result<usize> {
+ macro_rules! push_esc_sequence {
+ ($start:ident, $i:ident, $self:ident, $bytes:ident, $quote:expr) => {{
+ if $start < $i {
+ $self.0.extend_from_slice(&$bytes[$start..$i]);
+ }
+ $self.0.extend_from_slice($quote);
+ $start = $i + 1;
+ }};
+ }
+
+ self.0.reserve(bytes.len());
+ let mut start = 0;
+ for (i, b) in bytes.iter().enumerate() {
+ match *b {
+ b'&' => push_esc_sequence!(start, i, self, bytes, br#"\u0026"#),
+ b'\'' => push_esc_sequence!(start, i, self, bytes, br#"\u0027"#),
+ b'<' => push_esc_sequence!(start, i, self, bytes, br#"\u003c"#),
+ b'>' => push_esc_sequence!(start, i, self, bytes, br#"\u003e"#),
+ _ => (),
+ }
+ }
+ if start < bytes.len() {
+ self.0.extend_from_slice(&bytes[start..]);
+ }
+ Ok(bytes.len())
+ }
+
+ fn flush(&mut self) -> std::io::Result<()> {
+ Ok(())
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;