src/serialize/writer/json.rs (645 lines of code) (raw):

// SPDX-License-Identifier: (Apache-2.0 OR MIT) // This is an adaptation of `src/value/ser.rs` from serde-json. use crate::serialize::writer::formatter::{CompactFormatter, Formatter, PrettyFormatter}; use crate::serialize::writer::str::*; use crate::serialize::writer::WriteExt; use serde::ser::{self, Impossible, Serialize}; use serde_json::error::{Error, Result}; use std::io; pub struct Serializer<W, F = CompactFormatter> { writer: W, formatter: F, } impl<W> Serializer<W> where W: io::Write + WriteExt, { #[inline] pub fn new(writer: W) -> Self { Serializer::with_formatter(writer, CompactFormatter) } } impl<W> Serializer<W, PrettyFormatter> where W: io::Write + WriteExt, { #[inline] pub fn pretty(writer: W) -> Self { Serializer::with_formatter(writer, PrettyFormatter::new()) } } impl<W, F> Serializer<W, F> where W: io::Write + WriteExt, F: Formatter, { #[inline] pub fn with_formatter(writer: W, formatter: F) -> Self { Serializer { writer, formatter } } #[inline] pub fn into_inner(self) -> W { self.writer } } impl<'a, W, F> ser::Serializer for &'a mut Serializer<W, F> where W: io::Write + WriteExt, F: Formatter, { type Ok = (); type Error = Error; type SerializeSeq = Compound<'a, W, F>; type SerializeTuple = Impossible<(), Error>; type SerializeTupleStruct = Impossible<(), Error>; type SerializeTupleVariant = Impossible<(), Error>; type SerializeMap = Compound<'a, W, F>; type SerializeStruct = Impossible<(), Error>; type SerializeStructVariant = Impossible<(), Error>; #[inline] fn serialize_bool(self, value: bool) -> Result<()> { self.formatter .write_bool(&mut self.writer, value) .map_err(Error::io) } fn serialize_i8(self, _value: i8) -> Result<()> { unreachable!(); } fn serialize_i16(self, _value: i16) -> Result<()> { unreachable!(); } #[inline] fn serialize_i32(self, value: i32) -> Result<()> { self.formatter .write_i32(&mut self.writer, value) .map_err(Error::io) } #[inline] fn serialize_i64(self, value: i64) -> Result<()> { self.formatter .write_i64(&mut self.writer, value) .map_err(Error::io) } fn serialize_i128(self, _value: i128) -> Result<()> { unreachable!(); } fn serialize_u8(self, _value: u8) -> Result<()> { unreachable!(); } fn serialize_u16(self, _value: u16) -> Result<()> { unreachable!(); } #[inline] fn serialize_u32(self, value: u32) -> Result<()> { self.formatter .write_u32(&mut self.writer, value) .map_err(Error::io) } #[inline] fn serialize_u64(self, value: u64) -> Result<()> { self.formatter .write_u64(&mut self.writer, value) .map_err(Error::io) } fn serialize_u128(self, _value: u128) -> Result<()> { unreachable!(); } #[inline] fn serialize_f32(self, value: f32) -> Result<()> { #[cfg(yyjson_allow_inf_and_nan)] { if value.is_infinite() { if value.is_sign_positive() { unsafe { self.writer.write_reserved_fragment(b"Infinity").unwrap() }; Ok(()) } else { unsafe { self.writer.write_reserved_fragment(b"-Infinity").unwrap() }; Ok(()) } } else if value.is_nan() { unsafe { self.writer.write_reserved_fragment(b"NaN").unwrap() }; Ok(()) } else { self.formatter .write_f32(&mut self.writer, value) .map_err(Error::io) } } #[cfg(not(yyjson_allow_inf_and_nan))] { if unlikely!(value.is_infinite() || value.is_nan()) { self.serialize_unit() } else { self.formatter .write_f32(&mut self.writer, value) .map_err(Error::io) } } } #[inline] fn serialize_f64(self, value: f64) -> Result<()> { #[cfg(yyjson_allow_inf_and_nan)] { if value.is_infinite() { if value.is_sign_positive() { unsafe { self.writer.write_reserved_fragment(b"Infinity").unwrap() }; Ok(()) } else { unsafe { self.writer.write_reserved_fragment(b"-Infinity").unwrap() }; Ok(()) } } else if value.is_nan() { unsafe { self.writer.write_reserved_fragment(b"NaN").unwrap() }; Ok(()) } else { self.formatter .write_f64(&mut self.writer, value) .map_err(Error::io) } } #[cfg(not(yyjson_allow_inf_and_nan))] { if unlikely!(value.is_infinite() || value.is_nan()) { self.serialize_unit() } else { self.formatter .write_f64(&mut self.writer, value) .map_err(Error::io) } } } fn serialize_char(self, _value: char) -> Result<()> { unreachable!(); } #[inline(always)] fn serialize_str(self, value: &str) -> Result<()> { format_escaped_str(&mut self.writer, value); Ok(()) } #[inline(always)] fn serialize_bytes(self, value: &[u8]) -> Result<()> { self.writer.reserve(value.len() + 32); unsafe { self.writer.write_reserved_fragment(value).unwrap() }; Ok(()) } #[inline] fn serialize_unit(self) -> Result<()> { self.formatter .write_null(&mut self.writer) .map_err(Error::io) } #[inline(always)] fn serialize_unit_struct(self, name: &'static str) -> Result<()> { debug_assert!(name.len() <= 36); reserve_minimum!(self.writer); unsafe { self.writer.write_reserved_punctuation(b'"').unwrap(); self.writer .write_reserved_fragment(name.as_bytes()) .unwrap(); self.writer.write_reserved_punctuation(b'"').unwrap(); } Ok(()) } fn serialize_unit_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, ) -> Result<()> { unreachable!(); } fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<()> where T: ?Sized + Serialize, { unreachable!(); } fn serialize_newtype_variant<T>( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _value: &T, ) -> Result<()> where T: ?Sized + Serialize, { unreachable!(); } #[inline] fn serialize_none(self) -> Result<()> { self.serialize_unit() } #[inline] fn serialize_some<T>(self, value: &T) -> Result<()> where T: ?Sized + Serialize, { value.serialize(self) } #[inline(always)] fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { self.formatter .begin_array(&mut self.writer) .map_err(Error::io)?; Ok(Compound { ser: self, state: State::First, }) } fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> { unreachable!(); } fn serialize_tuple_struct( self, _name: &'static str, _len: usize, ) -> Result<Self::SerializeTupleStruct> { unreachable!(); } fn serialize_tuple_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize, ) -> Result<Self::SerializeTupleVariant> { unreachable!(); } #[inline(always)] fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> { self.formatter .begin_object(&mut self.writer) .map_err(Error::io)?; Ok(Compound { ser: self, state: State::First, }) } fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> { unreachable!(); } fn serialize_struct_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize, ) -> Result<Self::SerializeStructVariant> { unreachable!(); } } #[derive(Eq, PartialEq)] pub enum State { First, Rest, } pub struct Compound<'a, W: 'a, F: 'a> { ser: &'a mut Serializer<W, F>, state: State, } impl<'a, W, F> ser::SerializeSeq for Compound<'a, W, F> where W: io::Write + WriteExt, F: Formatter, { type Ok = (); type Error = Error; #[inline] fn serialize_element<T>(&mut self, value: &T) -> Result<()> where T: ?Sized + Serialize, { self.ser .formatter .begin_array_value(&mut self.ser.writer, self.state == State::First) .unwrap(); self.state = State::Rest; value.serialize(&mut *self.ser)?; self.ser .formatter .end_array_value(&mut self.ser.writer) .map_err(Error::io) .unwrap(); Ok(()) } #[inline] fn end(self) -> Result<()> { self.ser.formatter.end_array(&mut self.ser.writer).unwrap(); Ok(()) } } impl<'a, W, F> ser::SerializeMap for Compound<'a, W, F> where W: io::Write + WriteExt, F: Formatter, { type Ok = (); type Error = Error; fn serialize_entry<K, V>(&mut self, _key: &K, _value: &V) -> Result<()> where K: ?Sized + Serialize, V: ?Sized + Serialize, { unreachable!() } #[inline] fn serialize_key<T>(&mut self, key: &T) -> Result<()> where T: ?Sized + Serialize, { self.ser .formatter .begin_object_key(&mut self.ser.writer, self.state == State::First) .unwrap(); self.state = State::Rest; key.serialize(MapKeySerializer { ser: self.ser })?; self.ser .formatter .end_object_key(&mut self.ser.writer) .unwrap(); Ok(()) } #[inline] fn serialize_value<T>(&mut self, value: &T) -> Result<()> where T: ?Sized + Serialize, { self.ser .formatter .begin_object_value(&mut self.ser.writer) .unwrap(); value.serialize(&mut *self.ser)?; self.ser .formatter .end_object_value(&mut self.ser.writer) .unwrap(); Ok(()) } #[inline] fn end(self) -> Result<()> { self.ser.formatter.end_object(&mut self.ser.writer).unwrap(); Ok(()) } } #[repr(transparent)] struct MapKeySerializer<'a, W: 'a, F: 'a> { ser: &'a mut Serializer<W, F>, } impl<'a, W, F> ser::Serializer for MapKeySerializer<'a, W, F> where W: io::Write + WriteExt, F: Formatter, { type Ok = (); type Error = Error; type SerializeSeq = Impossible<(), Error>; type SerializeTuple = Impossible<(), Error>; type SerializeTupleStruct = Impossible<(), Error>; type SerializeTupleVariant = Impossible<(), Error>; type SerializeMap = Impossible<(), Error>; type SerializeStruct = Impossible<(), Error>; type SerializeStructVariant = Impossible<(), Error>; #[inline(always)] fn serialize_str(self, value: &str) -> Result<()> { self.ser.serialize_str(value) } fn serialize_unit_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, ) -> Result<()> { unreachable!(); } fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<()> where T: ?Sized + Serialize, { unreachable!(); } fn serialize_bool(self, _value: bool) -> Result<()> { unreachable!(); } fn serialize_i8(self, _value: i8) -> Result<()> { unreachable!(); } fn serialize_i16(self, _value: i16) -> Result<()> { unreachable!(); } fn serialize_i32(self, _value: i32) -> Result<()> { unreachable!(); } fn serialize_i64(self, _value: i64) -> Result<()> { unreachable!(); } fn serialize_i128(self, _value: i128) -> Result<()> { unreachable!(); } fn serialize_u8(self, _value: u8) -> Result<()> { unreachable!(); } fn serialize_u16(self, _value: u16) -> Result<()> { unreachable!(); } fn serialize_u32(self, _value: u32) -> Result<()> { unreachable!(); } fn serialize_u64(self, _value: u64) -> Result<()> { unreachable!(); } fn serialize_u128(self, _value: u128) -> Result<()> { unreachable!(); } fn serialize_f32(self, _value: f32) -> Result<()> { unreachable!(); } fn serialize_f64(self, _value: f64) -> Result<()> { unreachable!(); } fn serialize_char(self, _value: char) -> Result<()> { unreachable!(); } fn serialize_bytes(self, _value: &[u8]) -> Result<()> { unreachable!(); } fn serialize_unit(self) -> Result<()> { unreachable!(); } fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { unreachable!(); } fn serialize_newtype_variant<T>( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _value: &T, ) -> Result<()> where T: ?Sized + Serialize, { unreachable!(); } fn serialize_none(self) -> Result<()> { unreachable!(); } fn serialize_some<T>(self, _value: &T) -> Result<()> where T: ?Sized + Serialize, { unreachable!(); } fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { unreachable!(); } fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> { unreachable!(); } fn serialize_tuple_struct( self, _name: &'static str, _len: usize, ) -> Result<Self::SerializeTupleStruct> { unreachable!(); } fn serialize_tuple_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize, ) -> Result<Self::SerializeTupleVariant> { unreachable!(); } fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> { unreachable!(); } fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> { unreachable!(); } fn serialize_struct_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize, ) -> Result<Self::SerializeStructVariant> { unreachable!(); } } macro_rules! reserve_str { ($writer:expr, $value:expr) => { $writer.reserve($value.len() * 8 + 32); }; } #[cfg(all(feature = "unstable-simd", not(target_arch = "x86_64")))] #[inline(always)] fn format_escaped_str<W>(writer: &mut W, value: &str) where W: ?Sized + io::Write + WriteExt, { unsafe { reserve_str!(writer, value); let written = format_escaped_str_impl_generic_128( writer.as_mut_buffer_ptr(), value.as_bytes().as_ptr(), value.len(), ); writer.set_written(written); } } #[cfg(all( feature = "unstable-simd", target_arch = "x86_64", not(feature = "avx512") ))] #[inline(always)] fn format_escaped_str<W>(writer: &mut W, value: &str) where W: ?Sized + io::Write + WriteExt, { unsafe { reserve_str!(writer, value); let written = format_escaped_str_impl_sse2_128( writer.as_mut_buffer_ptr(), value.as_bytes().as_ptr(), value.len(), ); writer.set_written(written); } } #[cfg(all(feature = "unstable-simd", target_arch = "x86_64", feature = "avx512"))] #[inline(always)] fn format_escaped_str<W>(writer: &mut W, value: &str) where W: ?Sized + io::Write + WriteExt, { unsafe { reserve_str!(writer, value); if std::is_x86_feature_detected!("avx512vl") { let written = format_escaped_str_impl_512vl( writer.as_mut_buffer_ptr(), value.as_bytes().as_ptr(), value.len(), ); writer.set_written(written); } else { let written = format_escaped_str_impl_sse2_128( writer.as_mut_buffer_ptr(), value.as_bytes().as_ptr(), value.len(), ); writer.set_written(written); }; } } #[cfg(all(not(feature = "unstable-simd"), not(target_arch = "x86_64")))] #[inline(always)] fn format_escaped_str<W>(writer: &mut W, value: &str) where W: ?Sized + io::Write + WriteExt, { unsafe { reserve_str!(writer, value); let written = format_escaped_str_scalar( writer.as_mut_buffer_ptr(), value.as_bytes().as_ptr(), value.len(), ); writer.set_written(written); } } #[cfg(all(not(feature = "unstable-simd"), target_arch = "x86_64"))] #[inline(always)] fn format_escaped_str<W>(writer: &mut W, value: &str) where W: ?Sized + io::Write + WriteExt, { unsafe { reserve_str!(writer, value); let written = format_escaped_str_impl_sse2_128( writer.as_mut_buffer_ptr(), value.as_bytes().as_ptr(), value.len(), ); writer.set_written(written); } } #[inline] pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()> where W: io::Write + WriteExt, T: ?Sized + Serialize, { let mut ser = Serializer::new(writer); value.serialize(&mut ser) } #[inline] pub fn to_writer_pretty<W, T>(writer: W, value: &T) -> Result<()> where W: io::Write + WriteExt, T: ?Sized + Serialize, { let mut ser = Serializer::pretty(writer); value.serialize(&mut ser) }