#![doc = include_str!("../README.md")]
#![no_std]
use core::mem::ManuallyDrop;
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::string::String;
use sealed::sealed;
mod escape;
mod write_to_json;
pub use write_to_json::*;
#[inline]
#[cold]
fn cold() {}
pub trait JsonBuffer {
fn push(&mut self, c: char);
fn push_str(&mut self, s: &str);
fn reserve(&mut self, l: usize);
}
impl<S> JsonBuffer for &mut S
where
S: JsonBuffer,
{
#[inline(always)]
fn push(&mut self, c: char) {
(*self).push(c)
}
#[inline(always)]
fn push_str(&mut self, s: &str) {
(*self).push_str(s)
}
#[inline(always)]
fn reserve(&mut self, l: usize) {
(*self).reserve(l)
}
}
#[cfg(feature = "alloc")]
impl JsonBuffer for String {
#[inline(always)]
fn push(&mut self, c: char) {
self.push(c)
}
#[inline(always)]
fn push_str(&mut self, s: &str) {
self.push_str(s)
}
#[inline(always)]
fn reserve(&mut self, l: usize) {
self.reserve(l)
}
}
#[repr(transparent)]
pub struct Serializer<'a, S: JsonBuffer> {
buf: &'a mut S,
}
impl<'a, S: JsonBuffer> Serializer<'a, S> {
pub fn new(buf: &mut S) -> Serializer<S> {
Serializer { buf }
}
pub fn write(&mut self, val: impl WriteToJson<S>) {
val.write_to_json(self.buf)
}
pub fn array(&mut self) -> ArrayWriter<S> {
ArrayWriter::start(self.buf)
}
pub fn object(&mut self) -> ObjectWriter<S> {
ObjectWriter::start(self.buf)
}
pub fn end(self) {}
}
pub struct SingleValueSerializer<'a, S: JsonBuffer> {
guard: ManuallyDrop<&'a mut S>,
}
impl<'a, S: JsonBuffer> SingleValueSerializer<'a, S> {
pub fn new(val: &'a mut S) -> SingleValueSerializer<'a, S> {
SingleValueSerializer {
guard: ManuallyDrop::new(val),
}
}
pub fn write(mut self, val: impl WriteToJson<S>) {
let buf = unsafe { ManuallyDrop::<&'a mut S>::take(&mut self.guard) };
val.write_to_json(buf);
core::mem::forget(self);
}
pub fn array(mut self) -> ArrayWriter<'a, S> {
let buf = unsafe { ManuallyDrop::<&'a mut S>::take(&mut self.guard) };
let w = ArrayWriter::start(buf);
core::mem::forget(self);
w
}
pub fn object(mut self) -> ObjectWriter<'a, S> {
let buf = unsafe { ManuallyDrop::<&'a mut S>::take(&mut self.guard) };
let w = ObjectWriter::start(buf);
core::mem::forget(self);
w
}
}
impl<'a, S: JsonBuffer> Drop for SingleValueSerializer<'a, S> {
fn drop(&mut self) {
unsafe { ManuallyDrop::<&'a mut S>::take(&mut self.guard).push_str("null") };
}
}
pub struct ArrayWriter<'a, S: JsonBuffer> {
buf: &'a mut S,
first_element: bool,
}
impl<'a, S: JsonBuffer> ArrayWriter<'a, S> {
pub fn start(buf: &'a mut S) -> ArrayWriter<'a, S> {
buf.push('[');
ArrayWriter {
buf,
first_element: true,
}
}
fn comma(&mut self) {
match self.first_element {
true => {
cold();
self.first_element = false
}
false => self.buf.push(','),
}
}
pub fn add(&mut self, val: impl WriteToJson<S>) {
self.comma();
val.write_to_json(self.buf)
}
pub fn extend<V: WriteToJson<S>>(&mut self, vals: impl IntoIterator<Item = V>) {
for val in vals {
self.add(val);
}
}
pub fn add_complex<F, O>(&mut self, encoder: F) -> O
where
F: FnOnce(SingleValueSerializer<&mut S>) -> O,
{
self.comma();
encoder(SingleValueSerializer::new(&mut self.buf))
}
pub fn add_object(&mut self) -> ObjectWriter<S> {
self.comma();
ObjectWriter::start(self.buf)
}
pub fn add_array(&mut self) -> ArrayWriter<S> {
self.comma();
ArrayWriter::start(self.buf)
}
pub fn end(self) {}
}
impl<S: JsonBuffer> Drop for ArrayWriter<'_, S> {
fn drop(&mut self) {
self.buf.push(']');
}
}
#[sealed]
pub trait Key {
fn write<S: JsonBuffer>(self, out: &mut S);
}
#[sealed]
impl Key for UnescapedStr<'_> {
fn write<S: JsonBuffer>(self, out: &mut S) {
self.write_to_json(out)
}
}
#[sealed]
impl<T: AsRef<str>> Key for T {
fn write<S: JsonBuffer>(self, out: &mut S) {
self.as_ref().write_to_json(out)
}
}
pub struct ObjectWriter<'a, S: JsonBuffer> {
buf: &'a mut S,
first_element: bool,
}
impl<'a, S: JsonBuffer> ObjectWriter<'a, S> {
pub fn start(buf: &'a mut S) -> ObjectWriter<S> {
buf.push('{');
ObjectWriter {
buf,
first_element: true,
}
}
fn comma(&mut self) {
match self.first_element {
true => {
cold();
self.first_element = false
}
false => self.buf.push(','),
}
}
fn key<K: Key>(&mut self, key: K) {
self.comma();
key.write(&mut self.buf);
self.buf.push(':');
}
pub fn field<K: Key>(&mut self, key: K, val: impl WriteToJson<S>) {
self.key(key);
val.write_to_json(self.buf);
}
pub fn complex_field<K, F, O>(&mut self, key: K, encode: F) -> O
where
K: Key,
F: FnOnce(SingleValueSerializer<&mut S>) -> O,
{
self.key(key);
encode(SingleValueSerializer::new(&mut self.buf))
}
pub fn object_field<K: Key>(&mut self, key: K) -> ObjectWriter<S> {
self.key(key);
ObjectWriter::start(self.buf)
}
pub fn array_field<K: Key>(&mut self, key: K) -> ArrayWriter<S> {
self.key(key);
ArrayWriter::start(self.buf)
}
pub fn end(self) {}
}
impl<S: JsonBuffer> Drop for ObjectWriter<'_, S> {
fn drop(&mut self) {
self.buf.push('}');
}
}