feat: json filter

This commit is contained in:
Kogia-sima 2020-12-17 18:00:05 +09:00
parent 8e07927f19
commit d7bce02109
4 changed files with 90 additions and 8 deletions

18
Cargo.lock generated
View File

@ -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",

View File

@ -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"

View File

@ -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::*;

View File

@ -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) => {