use super::formatter::Formatter;
use crate::io;
#[derive(Clone, Debug)]
pub(crate) struct PrettyFormatter<'a> {
current_indent: usize,
has_value: bool,
indent: &'a [u8],
}
impl<'a> PrettyFormatter<'a> {
pub fn new() -> Self {
PrettyFormatter::with_indent(b" ")
}
pub fn with_indent(indent: &'a [u8]) -> Self {
PrettyFormatter {
current_indent: 0,
has_value: false,
indent,
}
}
}
impl<'a> Default for PrettyFormatter<'a> {
fn default() -> Self {
PrettyFormatter::new()
}
}
impl<'a> Formatter for PrettyFormatter<'a> {
#[inline]
fn begin_array<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
self.current_indent += 1;
self.has_value = false;
writer.write_all(b"[\n")?;
indent(writer, self.current_indent, self.indent)
}
#[inline]
fn end_array<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
self.current_indent -= 1;
if self.has_value {
writer.write_all(b"\n")?;
indent(writer, self.current_indent, self.indent)?;
}
writer.write_all(b"]")
}
#[inline]
fn begin_array_value<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
writer.write_all(b"\n")?;
indent(writer, self.current_indent, self.indent)
}
#[inline]
fn end_array_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
self.has_value = true;
Ok(())
}
#[inline]
fn begin_object<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
self.current_indent += 1;
self.has_value = false;
writer.write_all(b"{\n")?;
indent(writer, self.current_indent, self.indent)
}
#[inline]
fn end_object<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
self.current_indent -= 1;
if self.has_value {
writer.write_all(b"\n")?;
indent(writer, self.current_indent, self.indent)?;
}
writer.write_all(b"}")
}
#[inline]
fn begin_data_key<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where
W: ?Sized + io::Write,
{
if first {
Ok(())
} else {
writer.write_all(b"\n")?;
indent(writer, self.current_indent, self.indent)
}
}
#[inline]
fn begin_data<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
writer.write_all(b":")
}
#[inline]
fn end_data<W>(&mut self, _writer: &mut W) -> io::Result<()>
where
W: ?Sized + io::Write,
{
self.has_value = true;
Ok(())
}
}
fn indent<W>(wr: &mut W, n: usize, s: &[u8]) -> io::Result<()>
where
W: ?Sized + io::Write,
{
for _ in 0..n {
wr.write_all(s)?;
}
Ok(())
}