use minijinja::value::{Kwargs, Value};
use minijinja::{Error, ErrorKind};
use serde::Serialize;
use serde_json::ser::Formatter;
use std::io;
struct PythonCompact;
impl Formatter for PythonCompact {
#[inline]
fn begin_array_value<W: ?Sized + io::Write>(
&mut self,
w: &mut W,
first: bool,
) -> io::Result<()> {
if first {
Ok(())
} else {
w.write_all(b", ")
}
}
#[inline]
fn begin_object_key<W: ?Sized + io::Write>(
&mut self,
w: &mut W,
first: bool,
) -> io::Result<()> {
if first {
Ok(())
} else {
w.write_all(b", ")
}
}
#[inline]
fn begin_object_value<W: ?Sized + io::Write>(&mut self, w: &mut W) -> io::Result<()> {
w.write_all(b": ")
}
}
pub(crate) fn python_tojson(value: &Value, indent: Option<usize>) -> Result<String, Error> {
let mut buf: Vec<u8> = Vec::with_capacity(64);
match indent {
None => {
let mut ser = serde_json::Serializer::with_formatter(&mut buf, PythonCompact);
value
.serialize(&mut ser)
.map_err(|e| Error::new(ErrorKind::InvalidOperation, format!("tojson: {e}")))?;
}
Some(n) => {
let indent_bytes = vec![b' '; n];
let pretty = serde_json::ser::PrettyFormatter::with_indent(&indent_bytes);
let mut ser = serde_json::Serializer::with_formatter(&mut buf, pretty);
value
.serialize(&mut ser)
.map_err(|e| Error::new(ErrorKind::InvalidOperation, format!("tojson: {e}")))?;
}
}
Ok(String::from_utf8(buf).expect("serde_json emits valid UTF-8"))
}
pub(crate) fn tojson_filter(value: Value, kwargs: Kwargs) -> Result<String, Error> {
let indent: Option<usize> = kwargs.get("indent").unwrap_or(None);
python_tojson(&value, indent)
}