#![deny(missing_docs)]
#![doc = include_str!("../README.md")]
mod jiter_lite;
mod parser;
use jiter_lite::errors::JiterError;
use merde_core::{
Array, CowStr, IntoStatic, Map, MerdeError, OwnedValueDeserialize, Value, ValueDeserialize,
};
use parser::json_bytes_to_value;
use std::borrow::Cow;
use std::collections::HashMap;
use std::io::Write;
#[derive(Default)]
pub struct JsonSerializer {
buffer: Vec<u8>,
}
impl JsonSerializer {
pub fn from_vec(vec: Vec<u8>) -> Self {
JsonSerializer { buffer: vec }
}
pub fn new() -> Self {
Self::default()
}
pub fn write_null(&mut self) {
self.buffer.extend_from_slice(b"null");
}
pub fn write_bool(&mut self, value: bool) {
self.buffer
.extend_from_slice(if value { b"true" } else { b"false" });
}
pub fn write_i64(&mut self, value: i64) {
let _ = write!(self.buffer, "{}", value);
}
pub fn write_f64(&mut self, value: f64) {
let _ = write!(self.buffer, "{}", value);
}
pub fn write_str(&mut self, value: &str) {
self.buffer.push(b'"');
for c in value.chars() {
match c {
'"' => self.buffer.extend_from_slice(b"\\\""),
'\\' => self.buffer.extend_from_slice(b"\\\\"),
'\n' => self.buffer.extend_from_slice(b"\\n"),
'\r' => self.buffer.extend_from_slice(b"\\r"),
'\t' => self.buffer.extend_from_slice(b"\\t"),
c if c.is_control() => {
let _ = write!(self.buffer, "\\u{:04x}", c as u32);
}
c => self.buffer.extend_from_slice(c.to_string().as_bytes()),
}
}
self.buffer.push(b'"');
}
pub fn write_obj(&mut self) -> ObjectGuard<'_> {
self.buffer.push(b'{');
ObjectGuard {
serializer: self,
first: true,
}
}
pub fn write_arr(&mut self) -> ArrayGuard<'_> {
self.buffer.push(b'[');
ArrayGuard {
serializer: self,
first: true,
}
}
pub fn into_inner(self) -> Vec<u8> {
self.buffer
}
pub fn as_mut_vec(&mut self) -> &mut Vec<u8> {
&mut self.buffer
}
}
pub struct ObjectGuard<'a> {
serializer: &'a mut JsonSerializer,
first: bool,
}
impl<'a> ObjectGuard<'a> {
#[inline]
pub fn pair(&mut self, key: &str, value: &dyn JsonSerialize) -> &mut Self {
if !self.first {
self.serializer.buffer.push(b',');
}
self.first = false;
self.serializer.write_str(key);
self.serializer.buffer.push(b':');
value.json_serialize(self.serializer);
self
}
}
impl<'a> Drop for ObjectGuard<'a> {
#[inline]
fn drop(&mut self) {
self.serializer.buffer.push(b'}');
}
}
pub struct ArrayGuard<'a> {
serializer: &'a mut JsonSerializer,
first: bool,
}
impl<'a> ArrayGuard<'a> {
#[inline]
pub fn elem(&mut self, value: &dyn JsonSerialize) -> &mut Self {
if !self.first {
self.serializer.buffer.push(b',');
}
self.first = false;
value.json_serialize(self.serializer);
self
}
}
impl<'a> Drop for ArrayGuard<'a> {
#[inline]
fn drop(&mut self) {
self.serializer.buffer.push(b']');
}
}
pub trait JsonSerialize {
fn json_serialize(&self, s: &mut JsonSerializer);
fn to_json_bytes(&self) -> Vec<u8> {
let mut s = JsonSerializer::new();
self.json_serialize(&mut s);
s.into_inner()
}
fn to_json_string(&self) -> String {
unsafe { String::from_utf8_unchecked(self.to_json_bytes()) }
}
}
impl JsonSerialize for Value<'_> {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
match self {
Value::Null => serializer.write_null(),
Value::Bool(b) => serializer.write_bool(*b),
Value::Int(i) => serializer.write_i64(*i),
Value::Float(f) => serializer.write_f64(*f),
Value::Str(s) => serializer.write_str(s),
Value::Array(arr) => arr.json_serialize(serializer),
Value::Map(map) => map.json_serialize(serializer),
}
}
}
impl JsonSerialize for Map<'_> {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_obj();
for (key, value) in self.iter() {
guard.pair(key, value);
}
}
}
impl JsonSerialize for Array<'_> {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_arr();
for value in self.iter() {
guard.elem(value);
}
}
}
impl<T> JsonSerialize for &T
where
T: ?Sized + JsonSerialize,
{
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let this: &T = self;
JsonSerialize::json_serialize(this, serializer)
}
}
impl JsonSerialize for String {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_str(self)
}
}
impl<'s> JsonSerialize for &'s str {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_str(self)
}
}
impl<'s> JsonSerialize for Cow<'s, str> {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_str(self)
}
}
impl<'s> JsonSerialize for CowStr<'s> {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_str(self)
}
}
impl JsonSerialize for u8 {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_i64(*self as i64);
}
}
impl JsonSerialize for u16 {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_i64(*self as i64);
}
}
impl JsonSerialize for u32 {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_i64(*self as i64);
}
}
impl JsonSerialize for u64 {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_i64(*self as i64);
}
}
impl JsonSerialize for i8 {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_i64(*self as i64);
}
}
impl JsonSerialize for i16 {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_i64(*self as i64);
}
}
impl JsonSerialize for i32 {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_i64(*self as i64);
}
}
impl JsonSerialize for i64 {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_i64(*self);
}
}
impl JsonSerialize for usize {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_i64(*self as i64);
}
}
impl JsonSerialize for isize {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_i64(*self as i64);
}
}
impl JsonSerialize for bool {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
serializer.write_bool(*self);
}
}
impl<K: AsRef<str>, V: JsonSerialize> JsonSerialize for HashMap<K, V> {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_obj();
for (key, value) in self {
guard.pair(key.as_ref(), value);
}
}
}
impl<T: JsonSerialize> JsonSerialize for Vec<T> {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_arr();
for value in self {
guard.elem(value);
}
}
}
impl<T: JsonSerialize> JsonSerialize for Option<T> {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
match self {
Some(value) => value.json_serialize(serializer),
None => serializer.write_null(),
}
}
}
impl<T: JsonSerialize> JsonSerialize for &[T] {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_arr();
for value in *self {
guard.elem(value);
}
}
}
impl<T1: JsonSerialize> JsonSerialize for (T1,) {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_arr();
guard.elem(&self.0);
}
}
impl<T1: JsonSerialize, T2: JsonSerialize> JsonSerialize for (T1, T2) {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_arr();
guard.elem(&self.0);
guard.elem(&self.1);
}
}
impl<T1: JsonSerialize, T2: JsonSerialize, T3: JsonSerialize> JsonSerialize for (T1, T2, T3) {
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_arr();
guard.elem(&self.0);
guard.elem(&self.1);
guard.elem(&self.2);
}
}
impl<T1: JsonSerialize, T2: JsonSerialize, T3: JsonSerialize, T4: JsonSerialize> JsonSerialize
for (T1, T2, T3, T4)
{
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_arr();
guard.elem(&self.0);
guard.elem(&self.1);
guard.elem(&self.2);
guard.elem(&self.3);
}
}
impl<
T1: JsonSerialize,
T2: JsonSerialize,
T3: JsonSerialize,
T4: JsonSerialize,
T5: JsonSerialize,
> JsonSerialize for (T1, T2, T3, T4, T5)
{
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_arr();
guard.elem(&self.0);
guard.elem(&self.1);
guard.elem(&self.2);
guard.elem(&self.3);
guard.elem(&self.4);
}
}
impl<
T1: JsonSerialize,
T2: JsonSerialize,
T3: JsonSerialize,
T4: JsonSerialize,
T5: JsonSerialize,
T6: JsonSerialize,
> JsonSerialize for (T1, T2, T3, T4, T5, T6)
{
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_arr();
guard.elem(&self.0);
guard.elem(&self.1);
guard.elem(&self.2);
guard.elem(&self.3);
guard.elem(&self.4);
guard.elem(&self.5);
}
}
impl<
T1: JsonSerialize,
T2: JsonSerialize,
T3: JsonSerialize,
T4: JsonSerialize,
T5: JsonSerialize,
T6: JsonSerialize,
T7: JsonSerialize,
> JsonSerialize for (T1, T2, T3, T4, T5, T6, T7)
{
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_arr();
guard.elem(&self.0);
guard.elem(&self.1);
guard.elem(&self.2);
guard.elem(&self.3);
guard.elem(&self.4);
guard.elem(&self.5);
guard.elem(&self.6);
}
}
impl<
T1: JsonSerialize,
T2: JsonSerialize,
T3: JsonSerialize,
T4: JsonSerialize,
T5: JsonSerialize,
T6: JsonSerialize,
T7: JsonSerialize,
T8: JsonSerialize,
> JsonSerialize for (T1, T2, T3, T4, T5, T6, T7, T8)
{
fn json_serialize(&self, serializer: &mut JsonSerializer) {
let mut guard = serializer.write_arr();
guard.elem(&self.0);
guard.elem(&self.1);
guard.elem(&self.2);
guard.elem(&self.3);
guard.elem(&self.4);
guard.elem(&self.5);
guard.elem(&self.6);
guard.elem(&self.7);
}
}
pub enum MerdeJsonError<'s> {
MerdeError(MerdeError),
Utf8Error(std::str::Utf8Error),
JiterError {
err: JiterError,
source: Option<CowStr<'s>>,
},
}
impl<'s> MerdeJsonError<'s> {
pub fn without_source(self) -> MerdeJsonError<'static> {
match self {
MerdeJsonError::MerdeError(e) => MerdeJsonError::MerdeError(e),
MerdeJsonError::Utf8Error(e) => MerdeJsonError::Utf8Error(e),
MerdeJsonError::JiterError { err, source: _ } => {
MerdeJsonError::JiterError { err, source: None }
}
}
}
pub fn to_static(self) -> MerdeJsonError<'static> {
match self {
MerdeJsonError::MerdeError(e) => MerdeJsonError::MerdeError(e),
MerdeJsonError::Utf8Error(e) => MerdeJsonError::Utf8Error(e),
MerdeJsonError::JiterError { err, source } => MerdeJsonError::JiterError {
err,
source: source.map(|s| s.into_static()),
},
}
}
}
impl From<std::str::Utf8Error> for MerdeJsonError<'_> {
fn from(e: std::str::Utf8Error) -> Self {
MerdeJsonError::Utf8Error(e)
}
}
impl<'s> std::fmt::Display for MerdeJsonError<'s> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MerdeJsonError::MerdeError(me) => write!(f, "Merde Error: {}", me),
MerdeJsonError::Utf8Error(ue) => write!(f, "UTF-8 Error: {}", ue),
MerdeJsonError::JiterError { err, source } => {
writeln!(f, "JSON parsing error: \x1b[31m{}\x1b[0m", err.error_type)?;
if let Some(source) = source {
let context_start = err.index.saturating_sub(20);
let context_end = (err.index + 20).min(source.len());
let context = &source[context_start..context_end];
write!(f, "Source: ")?;
for (i, c) in context.char_indices() {
if i + context_start == err.index {
write!(f, "\x1b[48;2;255;200;200m\x1b[97m{}\x1b[0m", c)?;
} else {
write!(f, "\x1b[48;2;200;200;255m\x1b[97m{}\x1b[0m", c)?;
}
}
writeln!(f)?;
} else {
writeln!(f, "Error context: (not attached)")?;
}
Ok(())
}
}
}
}
impl<'s> std::error::Error for MerdeJsonError<'s> {}
impl<'s> std::fmt::Debug for MerdeJsonError<'s> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self, f)
}
}
impl From<MerdeError> for MerdeJsonError<'_> {
fn from(e: MerdeError) -> Self {
MerdeJsonError::MerdeError(e)
}
}
pub fn from_slice_via_value<'s, T>(data: &'s [u8]) -> Result<T, MerdeJsonError<'s>>
where
T: ValueDeserialize<'s>,
{
from_str_via_value(std::str::from_utf8(data)?)
}
pub fn from_str_via_value<'s, T>(s: &'s str) -> Result<T, MerdeJsonError<'s>>
where
T: ValueDeserialize<'s>,
{
let value = json_bytes_to_value(s.as_bytes()).map_err(|e| MerdeJsonError::JiterError {
err: e,
source: Some(s.into()),
})?;
Ok(merde_core::from_value(value)?)
}
pub fn owned_from_str_via_value<T>(s: &str) -> Result<T, MerdeJsonError<'_>>
where
T: OwnedValueDeserialize,
{
let value = json_bytes_to_value(s.as_bytes()).map_err(|e| MerdeJsonError::JiterError {
err: e,
source: Some(s.into()),
})?;
Ok(merde_core::OwnedValueDeserialize::owned_from_value(Some(
value,
))?)
}
pub fn to_string<T: JsonSerialize>(value: &T) -> String {
value.to_json_string()
}
pub fn to_vec<T: JsonSerialize>(value: &T) -> Vec<u8> {
value.to_json_bytes()
}
pub fn to_writer<W, T>(mut writer: impl std::io::Write, value: &T) -> std::io::Result<()>
where
T: JsonSerialize,
{
let bytes = value.to_json_bytes();
writer.write_all(&bytes)
}