1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
mod encode; mod entities; use encode::encode_attribute; use encode::encode_attribute_w; use std::io::Write; use std::io; use std::fmt::Write as WriteFmt; pub struct Escaped<T: AsRef<str>> { inner: T } impl<T: AsRef<str>> Escaped<T> { pub fn into_inner(self) -> T { self.inner } } pub trait Append<T> { fn append_str(self, string: T) -> Escaped<String>; } impl<T: AsRef<str>> Append<T> for Escaped<String> { fn append_str(mut self, string: T) -> Escaped<String> { self.inner.write_str(encode_attribute(string.as_ref()).as_ref()); self } } impl<T: AsRef<str>> Append<Escaped<T>> for Escaped<String> { fn append_str(mut self, string: Escaped<T>) -> Escaped<String> { self.inner.write_str(string.into_inner().as_ref()); self } } impl<T: AsRef<str>> Escaped<T> { fn as_ref(&self) -> &str { self.inner.as_ref() } } pub struct SafeWriter<T: Write> { inner: T } impl<T: Write> SafeWriter<T> { pub fn new(inner: T) -> Self { SafeWriter { inner: inner } } pub fn into_inner(self) -> T { self.inner } } pub trait Escapable: AsRef<str> { fn escape(&self) -> Escaped<String>; fn safe(&self) -> Escaped<String>; } pub trait SafeWrite<T> { fn write_str(&mut self, buffer: T) -> io::Result<()>; } impl<T: AsRef<str>> Escapable for T { fn escape(&self) -> Escaped<String> { Escaped { inner: encode_attribute(self.as_ref()) } } fn safe(&self) -> Escaped<String> { Escaped { inner: self.as_ref().into() } } } impl<X: AsRef<str>, W: Write> SafeWrite<Escaped<X>> for SafeWriter<W> { fn write_str(&mut self, buffer: Escaped<X>) -> io::Result<()> { self.inner.write_all(buffer.as_ref().as_bytes()) } } impl<'a, X: Escapable, W: Write> SafeWrite<X> for SafeWriter<W> { fn write_str(&mut self, buffer: X) -> io::Result<()> { encode_attribute_w(buffer.as_ref(), &mut self.inner) } }