feat: json filter
This commit is contained in:
parent
8e07927f19
commit
d7bce02109
|
@ -133,6 +133,8 @@ dependencies = [
|
|||
"itoap",
|
||||
"ryu",
|
||||
"sailfish-macros",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
|
@ -159,18 +161,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.111"
|
||||
version = "1.0.118"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d"
|
||||
checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.111"
|
||||
version = "1.0.118"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250"
|
||||
checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -179,9 +181,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.53"
|
||||
version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2"
|
||||
checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -190,9 +192,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.30"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93a56fabc59dce20fe48b6c832cc249c713e7ed88fa28b0ee0a3bfcaae5fe4e2"
|
||||
checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -15,11 +15,14 @@ edition = "2018"
|
|||
[features]
|
||||
default = ["derive", "perf-inline"]
|
||||
derive = ["sailfish-macros"]
|
||||
json = ["serde", "serde_json"]
|
||||
perf-inline = []
|
||||
|
||||
[dependencies]
|
||||
itoap = "0.1.0"
|
||||
ryu = "1.0.4"
|
||||
serde = { version = "1.0.118", optional = true }
|
||||
serde_json = { version = "1.0.60", optional = true }
|
||||
|
||||
[dependencies.sailfish-macros]
|
||||
path = "../sailfish-macros"
|
||||
|
|
|
@ -146,6 +146,73 @@ pub fn trim<T: Render>(expr: &T) -> Trim<T> {
|
|||
Trim(expr)
|
||||
}
|
||||
|
||||
cfg_json! {
|
||||
pub struct Json<'a, T>(&'a T);
|
||||
|
||||
impl<'a, T: serde::Serialize> Render for Json<'a, T> {
|
||||
#[inline]
|
||||
fn render(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
struct Writer<'a>(&'a mut Buffer);
|
||||
|
||||
impl<'a> std::io::Write for Writer<'a> {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||
let buf = unsafe { std::str::from_utf8_unchecked(buf) };
|
||||
self.0.push_str(buf);
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
|
||||
self.write(buf).map(|_| {})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
serde_json::to_writer(Writer(b), self.0)
|
||||
.map_err(|e| RenderError::new(&e.to_string()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn render_escaped(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
use super::escape::escape_to_buf;
|
||||
|
||||
struct Writer<'a>(&'a mut Buffer);
|
||||
|
||||
impl<'a> std::io::Write for Writer<'a> {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||
let buf = unsafe { std::str::from_utf8_unchecked(buf) };
|
||||
escape_to_buf(buf, self.0);
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
|
||||
self.write(buf).map(|_| {})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
serde_json::to_writer(Writer(b), self.0)
|
||||
.map_err(|e| RenderError::new(&e.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn json<T: serde::Serialize>(expr: &T) -> Json<T> {
|
||||
Json(expr)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
use std::ptr;
|
||||
|
||||
macro_rules! cfg_json {
|
||||
($($item:item)*) => {
|
||||
$(
|
||||
#[cfg(feature = "json")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
|
||||
$item
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(sailfish_nightly)]
|
||||
macro_rules! likely {
|
||||
($val:expr) => {
|
||||
|
|
Loading…
Reference in New Issue