diff options
Diffstat (limited to '')
| -rw-r--r-- | askama_shared/src/escaping.rs | 52 | 
1 files changed, 20 insertions, 32 deletions
diff --git a/askama_shared/src/escaping.rs b/askama_shared/src/escaping.rs index 8bb8f0b..6390f0c 100644 --- a/askama_shared/src/escaping.rs +++ b/askama_shared/src/escaping.rs @@ -55,46 +55,34 @@ pub struct Escaped<'a> {      bytes: &'a [u8],  } -enum State { -    Empty, -    Unescaped(usize), +macro_rules! escaping_body { +    ($state:ident, $i:ident, $fmt:ident, $_self:ident, $quote:expr) => {{ +        if $state < $i { +            $fmt.write_str(unsafe { str::from_utf8_unchecked(&$_self.bytes[$state..$i]) })?; +        } +        $fmt.write_str($quote)?; +        $state = $i + 1; +    }};  }  impl<'a> ::std::fmt::Display for Escaped<'a> {      fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { -        use self::State::*; -        let mut state = Empty; +        let mut state = 0;          for (i, b) in self.bytes.iter().enumerate() { -            let next = if b.wrapping_sub(b'"') <= FLAG { +            if b.wrapping_sub(b'"') <= FLAG {                  match *b { -                    b'<' => Some("<"), -                    b'>' => Some(">"), -                    b'&' => Some("&"), -                    b'"' => Some("""), -                    b'\'' => Some("'"), -                    b'/' => Some("/"), -                    _ => None, -                } -            } else { -                None -            }; -            state = match (state, next) { -                (Empty, None) => Unescaped(i), -                (s @ Unescaped(_), None) => s, -                (Empty, Some(escaped)) => { -                    fmt.write_str(escaped)?; -                    Empty -                } -                (Unescaped(start), Some(escaped)) => { -                    fmt.write_str(unsafe { str::from_utf8_unchecked(&self.bytes[start..i]) })?; -                    fmt.write_str(escaped)?; -                    Empty +                    b'<' => escaping_body!(state, i, fmt, self, "<"), +                    b'>' => escaping_body!(state, i, fmt, self, ">"), +                    b'&' => escaping_body!(state, i, fmt, self, "&"), +                    b'"' => escaping_body!(state, i, fmt, self, """), +                    b'\'' => escaping_body!(state, i, fmt, self, "'"), +                    b'/' => escaping_body!(state, i, fmt, self, "/"), +                    _ => (),                  } -            }; -        } -        if let Unescaped(start) = state { -            fmt.write_str(unsafe { str::from_utf8_unchecked(&self.bytes[start..]) })?; +            }          } + +        fmt.write_str(unsafe { str::from_utf8_unchecked(&self.bytes[state..]) })?;          Ok(())      }  }  | 
