use std::io::{self, Write};
use crate::{serde::tri, util::string::format_string, writer::WriteExt};
pub trait Formatter {
#[inline]
fn write_null<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
writer.write_all(b"null")
}
#[inline]
fn write_bool<W>(&mut self, writer: &mut W, value: bool) -> io::Result<()>
where
W: ?Sized + Write,
{
if value {
writer.write_all(b"true")
} else {
writer.write_all(b"false")
}
}
#[inline]
fn write_i8<W>(&mut self, writer: &mut W, value: i8) -> io::Result<()>
where
W: ?Sized + Write,
{
let mut buffer = itoa::Buffer::new();
let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
#[inline]
fn write_i16<W>(&mut self, writer: &mut W, value: i16) -> io::Result<()>
where
W: ?Sized + Write,
{
let mut buffer = itoa::Buffer::new();
let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
#[inline]
fn write_i32<W>(&mut self, writer: &mut W, value: i32) -> io::Result<()>
where
W: ?Sized + Write,
{
let mut buffer = itoa::Buffer::new();
let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
#[inline]
fn write_i64<W>(&mut self, writer: &mut W, value: i64) -> io::Result<()>
where
W: ?Sized + Write,
{
let mut buffer = itoa::Buffer::new();
let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
#[inline]
fn write_i128<W>(&mut self, writer: &mut W, value: i128) -> io::Result<()>
where
W: ?Sized + Write,
{
let mut buffer = itoa::Buffer::new();
let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
#[inline]
fn write_u8<W>(&mut self, writer: &mut W, value: u8) -> io::Result<()>
where
W: ?Sized + Write,
{
let mut buffer = itoa::Buffer::new();
let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
#[inline]
fn write_u16<W>(&mut self, writer: &mut W, value: u16) -> io::Result<()>
where
W: ?Sized + Write,
{
let mut buffer = itoa::Buffer::new();
let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
#[inline]
fn write_u32<W>(&mut self, writer: &mut W, value: u32) -> io::Result<()>
where
W: ?Sized + Write,
{
let mut buffer = itoa::Buffer::new();
let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
#[inline]
fn write_u64<W>(&mut self, writer: &mut W, value: u64) -> io::Result<()>
where
W: ?Sized + Write,
{
let mut buffer = itoa::Buffer::new();
let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
#[inline]
fn write_u128<W>(&mut self, writer: &mut W, value: u128) -> io::Result<()>
where
W: ?Sized + Write,
{
let mut buffer = itoa::Buffer::new();
let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
#[inline]
fn write_f32<W>(&mut self, writer: &mut W, value: f32) -> io::Result<()>
where
W: ?Sized + Write,
{
let mut buffer = ryu::Buffer::new();
let s = buffer.format_finite(value);
writer.write_all(s.as_bytes())
}
#[inline]
fn write_f64<W>(&mut self, writer: &mut W, value: f64) -> io::Result<()>
where
W: ?Sized + Write,
{
let mut buffer = ryu::Buffer::new();
let s = buffer.format_finite(value);
writer.write_all(s.as_bytes())
}
#[inline]
fn write_number_str<W>(&mut self, writer: &mut W, value: &str) -> io::Result<()>
where
W: ?Sized + Write,
{
writer.write_all(value.as_bytes())
}
#[inline]
fn write_string_fast<W>(
&mut self,
writer: &mut W,
value: &str,
need_quote: bool,
) -> io::Result<()>
where
W: ?Sized + WriteExt,
{
let buf = writer.reserve_with(value.len() * 6 + 32 + 3)?;
let cnt = format_string(value, buf, need_quote);
unsafe { writer.flush_len(cnt) };
Ok(())
}
fn write_byte_array<W>(&mut self, writer: &mut W, value: &[u8]) -> io::Result<()>
where
W: ?Sized + Write,
{
tri!(self.begin_array(writer));
let mut first = true;
for byte in value {
tri!(self.begin_array_value(writer, first));
tri!(self.write_u8(writer, *byte));
tri!(self.end_array_value(writer));
first = false;
}
self.end_array(writer)
}
#[inline]
fn begin_string<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
writer.write_all(b"\"")
}
#[inline]
fn end_string<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
writer.write_all(b"\"")
}
#[inline]
fn begin_array<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
writer.write_all(b"[")
}
#[inline]
fn end_array<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
writer.write_all(b"]")
}
#[inline]
fn begin_array_value<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where
W: ?Sized + Write,
{
if first {
Ok(())
} else {
writer.write_all(b",")
}
}
#[inline]
fn end_array_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
Ok(())
}
#[inline]
fn begin_object<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
writer.write_all(b"{")
}
#[inline]
fn end_object<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
writer.write_all(b"}")
}
#[inline]
fn begin_object_key<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where
W: ?Sized + Write,
{
if first {
Ok(())
} else {
writer.write_all(b",")
}
}
#[inline]
fn end_object_key<W>(&mut self, _writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
Ok(())
}
#[inline]
fn begin_object_value<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
writer.write_all(b":")
}
#[inline]
fn end_object_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
Ok(())
}
#[inline]
fn write_raw_value<W>(&mut self, writer: &mut W, raw: &str) -> io::Result<()>
where
W: ?Sized + Write,
{
writer.write_all(raw.as_bytes())
}
}
#[derive(Clone, Debug)]
pub struct CompactFormatter;
impl Formatter for CompactFormatter {}
#[derive(Clone, Debug)]
pub 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 + Write,
{
self.current_indent += 1;
self.has_value = false;
writer.write_all(b"[")
}
#[inline]
fn end_array<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
self.current_indent -= 1;
if self.has_value {
tri!(writer.write_all(b"\n"));
tri!(indent(writer, self.current_indent, self.indent));
}
writer.write_all(b"]")
}
#[inline]
fn begin_array_value<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where
W: ?Sized + Write,
{
tri!(writer.write_all(if first { b"\n" } else { 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 + Write,
{
self.has_value = true;
Ok(())
}
#[inline]
fn begin_object<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
self.current_indent += 1;
self.has_value = false;
writer.write_all(b"{")
}
#[inline]
fn end_object<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
self.current_indent -= 1;
if self.has_value {
tri!(writer.write_all(b"\n"));
tri!(indent(writer, self.current_indent, self.indent));
}
writer.write_all(b"}")
}
#[inline]
fn begin_object_key<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where
W: ?Sized + Write,
{
tri!(writer.write_all(if first { b"\n" } else { b",\n" }));
indent(writer, self.current_indent, self.indent)
}
#[inline]
fn begin_object_value<W>(&mut self, writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
writer.write_all(b": ")
}
#[inline]
fn end_object_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
where
W: ?Sized + Write,
{
self.has_value = true;
Ok(())
}
}
fn indent<W>(wr: &mut W, n: usize, s: &[u8]) -> io::Result<()>
where
W: ?Sized + Write,
{
for _ in 0..n {
tri!(wr.write_all(s));
}
Ok(())
}