use std::io::{self, Write};
use serde::ser::{self, Impossible, Serialize};
use crate::error::{Error, Result};
use crate::tokens::{strip_ctor, TOKEN_CTOR, TOKEN_INT, TOKEN_UINT};
const MAX_SAFE_INTEGER: i64 = (1 << 53) - 1;
const MIN_SAFE_INTEGER: i64 = -((1 << 53) - 1);
pub fn to_string<T: ?Sized + Serialize>(value: &T) -> Result<String> {
let bytes = to_vec(value)?;
Ok(unsafe { String::from_utf8_unchecked(bytes) })
}
pub fn to_string_pretty<T: ?Sized + Serialize>(value: &T) -> Result<String> {
to_string_indent(value, "", " ")
}
pub fn to_string_indent<T: ?Sized + Serialize>(
value: &T,
prefix: &str,
indent: &str,
) -> Result<String> {
let mut out = Vec::with_capacity(128);
let mut ser = Serializer::pretty(&mut out, prefix, indent);
value.serialize(&mut ser)?;
Ok(unsafe { String::from_utf8_unchecked(out) })
}
pub fn to_vec<T: ?Sized + Serialize>(value: &T) -> Result<Vec<u8>> {
let mut out = Vec::with_capacity(128);
let mut ser = Serializer::new(&mut out);
value.serialize(&mut ser)?;
Ok(out)
}
pub fn to_writer<W: Write, T: ?Sized + Serialize>(writer: W, value: &T) -> Result<()> {
let mut ser = Serializer::new(writer);
value.serialize(&mut ser)
}
pub fn to_writer_pretty<W: Write, T: ?Sized + Serialize>(writer: W, value: &T) -> Result<()> {
let mut ser = Serializer::pretty(writer, "", " ");
value.serialize(&mut ser)
}
#[inline]
fn is_atom(key: &str) -> bool {
crate::tokens::is_ident(key)
}
#[cold]
fn non_finite_error<T: std::fmt::Display>(value: T) -> Error {
Error::message(format!("cannot serialize non-finite number {value}"))
}
pub struct Serializer<W> {
writer: W,
pretty: bool,
level: usize,
prefix: String,
indent: String,
}
impl<W: Write> Serializer<W> {
pub fn new(writer: W) -> Self {
Serializer {
writer,
pretty: false,
level: 0,
prefix: String::new(),
indent: String::new(),
}
}
pub fn pretty(writer: W, prefix: &str, indent: &str) -> Self {
Serializer {
writer,
pretty: true,
level: 0,
prefix: prefix.to_owned(),
indent: indent.to_owned(),
}
}
fn write_indent(&mut self) -> io::Result<()> {
if self.pretty {
self.writer.write_all(b"\n")?;
self.writer.write_all(self.prefix.as_bytes())?;
for _ in 0..self.level {
self.writer.write_all(self.indent.as_bytes())?;
}
}
Ok(())
}
fn begin_item(&mut self, first: bool) -> io::Result<()> {
if !first {
self.writer.write_all(b",")?;
}
self.write_indent()
}
fn write_colon(&mut self) -> io::Result<()> {
self.writer.write_all(b":")?;
if self.pretty {
self.writer.write_all(b" ")?;
}
Ok(())
}
fn write_key(&mut self, key: &str) -> io::Result<()> {
if is_atom(key) {
self.writer.write_all(key.as_bytes())
} else {
self.write_string(key)
}
}
fn write_integer_float(&mut self, n: i64) -> Result<()> {
let mut buf = [0u8; crate::number::INT_BUF];
let len = crate::number::fmt_i64(n, &mut buf);
self.writer.write_all(&buf[..len])?;
self.writer.write_all(b".0")?;
Ok(())
}
fn write_string(&mut self, s: &str) -> io::Result<()> {
self.writer.write_all(b"\"")?;
let bytes = s.as_bytes();
let mut start = 0;
let mut i = 0;
while i < bytes.len() {
let b = bytes[i];
if (b == b'"') | (b == b'\\') | (b < 0x20) {
if start < i {
self.writer.write_all(&bytes[start..i])?;
}
match b {
b'"' => self.writer.write_all(b"\\\"")?,
b'\\' => self.writer.write_all(b"\\\\")?,
b'\n' => self.writer.write_all(b"\\n")?,
b'\r' => self.writer.write_all(b"\\r")?,
b'\t' => self.writer.write_all(b"\\t")?,
0x08 => self.writer.write_all(b"\\b")?,
0x0C => self.writer.write_all(b"\\f")?,
c => write!(self.writer, "\\u{:04x}", c)?,
}
start = i + 1;
}
i += 1;
}
if start < bytes.len() {
self.writer.write_all(&bytes[start..])?;
}
self.writer.write_all(b"\"")
}
fn open_variant(&mut self, variant: &str) -> Result<()> {
self.writer.write_all(b"{")?;
if self.pretty {
self.level += 1;
}
self.begin_item(true)?;
self.write_key(variant)?;
self.write_colon()?;
Ok(())
}
fn close_variant_wrapper(&mut self) -> Result<()> {
if self.pretty {
self.level -= 1;
self.write_indent()?;
}
self.writer.write_all(b"}")?;
Ok(())
}
}
enum Container {
Array,
Object,
}
pub struct Compound<'a, W> {
ser: &'a mut Serializer<W>,
first: bool,
container: Container,
variant: bool,
}
impl<'a, W: Write> Compound<'a, W> {
fn item(&mut self) -> Result<()> {
self.ser.begin_item(self.first)?;
self.first = false;
Ok(())
}
fn finish(self) -> Result<()> {
let close: &[u8] = match self.container {
Container::Array => b"]",
Container::Object => b"}",
};
if self.ser.pretty {
self.ser.level -= 1;
if !self.first {
self.ser.write_indent()?;
}
}
self.ser.writer.write_all(close)?;
if self.variant {
self.ser.close_variant_wrapper()?;
}
Ok(())
}
}
macro_rules! serialize_typed_int {
($method:ident, $ty:ty, $prefix:literal) => {
fn $method(self, value: $ty) -> Result<()> {
let mut buf = [0u8; crate::number::INT_BUF];
let n = crate::number::fmt_i64(value as i64, &mut buf);
self.writer.write_all($prefix)?;
self.writer.write_all(&buf[..n])?;
self.writer.write_all(b")")?;
Ok(())
}
};
}
impl<'a, W: Write> ser::Serializer for &'a mut Serializer<W> {
type Ok = ();
type Error = Error;
type SerializeSeq = Compound<'a, W>;
type SerializeTuple = Compound<'a, W>;
type SerializeTupleStruct = Compound<'a, W>;
type SerializeTupleVariant = Compound<'a, W>;
type SerializeMap = Compound<'a, W>;
type SerializeStruct = Compound<'a, W>;
type SerializeStructVariant = Compound<'a, W>;
fn serialize_bool(self, value: bool) -> Result<()> {
self.writer
.write_all(if value { b"true" } else { b"false" })?;
Ok(())
}
serialize_typed_int!(serialize_i8, i8, b"int8(");
serialize_typed_int!(serialize_i16, i16, b"int16(");
serialize_typed_int!(serialize_i32, i32, b"int32(");
serialize_typed_int!(serialize_u8, u8, b"uint8(");
serialize_typed_int!(serialize_u16, u16, b"uint16(");
serialize_typed_int!(serialize_u32, u32, b"uint32(");
fn serialize_i64(self, value: i64) -> Result<()> {
self.writer.write_all(b"int64(")?;
let quote = !(MIN_SAFE_INTEGER..=MAX_SAFE_INTEGER).contains(&value);
if quote {
self.writer.write_all(b"\"")?;
}
let mut buf = [0u8; crate::number::INT_BUF];
let n = crate::number::fmt_i64(value, &mut buf);
self.writer.write_all(&buf[..n])?;
if quote {
self.writer.write_all(b"\"")?;
}
self.writer.write_all(b")")?;
Ok(())
}
fn serialize_u64(self, value: u64) -> Result<()> {
self.writer.write_all(b"uint64(")?;
let quote = value > MAX_SAFE_INTEGER as u64;
if quote {
self.writer.write_all(b"\"")?;
}
let mut buf = [0u8; crate::number::INT_BUF];
let n = crate::number::fmt_u64(value, &mut buf);
self.writer.write_all(&buf[..n])?;
if quote {
self.writer.write_all(b"\"")?;
}
self.writer.write_all(b")")?;
Ok(())
}
fn serialize_i128(self, value: i128) -> Result<()> {
if let Ok(v) = i64::try_from(value) {
self.serialize_i64(v)
} else {
write!(self.writer, "{value}")?;
Ok(())
}
}
fn serialize_u128(self, value: u128) -> Result<()> {
if let Ok(v) = u64::try_from(value) {
self.serialize_u64(v)
} else {
write!(self.writer, "{value}")?;
Ok(())
}
}
fn serialize_f32(self, value: f32) -> Result<()> {
if !value.is_finite() {
return Err(non_finite_error(value));
}
if value != 0.0 && value.fract() == 0.0 && value.abs() < (1u32 << 24) as f32 {
return self.write_integer_float(value as i64);
}
let mut buf = ryu::Buffer::new();
self.writer.write_all(buf.format_finite(value).as_bytes())?;
Ok(())
}
fn serialize_f64(self, value: f64) -> Result<()> {
if !value.is_finite() {
return Err(non_finite_error(value));
}
if value != 0.0 && value.fract() == 0.0 && value.abs() < 1e16 {
return self.write_integer_float(value as i64);
}
let mut buf = ryu::Buffer::new();
self.writer.write_all(buf.format_finite(value).as_bytes())?;
Ok(())
}
fn serialize_char(self, value: char) -> Result<()> {
let mut buf = [0u8; 4];
self.write_string(value.encode_utf8(&mut buf))?;
Ok(())
}
fn serialize_str(self, value: &str) -> Result<()> {
self.write_string(value)?;
Ok(())
}
fn serialize_bytes(self, value: &[u8]) -> Result<()> {
self.writer.write_all(b"bytes(\"")?;
self.writer.write_all(crate::base64::encode(value).as_bytes())?;
self.writer.write_all(b"\")")?;
Ok(())
}
fn serialize_none(self) -> Result<()> {
self.serialize_unit()
}
fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<()> {
value.serialize(self)
}
fn serialize_unit(self) -> Result<()> {
self.writer.write_all(b"null")?;
Ok(())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
self.serialize_unit()
}
fn serialize_unit_variant(
self,
_name: &'static str,
_index: u32,
variant: &'static str,
) -> Result<()> {
self.write_string(variant)?;
Ok(())
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(
self,
name: &'static str,
value: &T,
) -> Result<()> {
match name {
TOKEN_INT => {
self.writer.write_all(b"int(")?;
value.serialize(BareInt {
writer: &mut self.writer,
})?;
self.writer.write_all(b")")?;
Ok(())
}
TOKEN_UINT => {
self.writer.write_all(b"uint(")?;
value.serialize(BareInt {
writer: &mut self.writer,
})?;
self.writer.write_all(b")")?;
Ok(())
}
TOKEN_CTOR => value.serialize(CtorEmitter { ser: self }),
_ => match strip_ctor(name) {
Some(ctor) => {
if !crate::tokens::is_ident(ctor) {
return Err(ctor_name_error(ctor));
}
self.writer.write_all(ctor.as_bytes())?;
self.writer.write_all(b"(")?;
value.serialize(&mut *self)?;
self.writer.write_all(b")")?;
Ok(())
}
None => value.serialize(self),
},
}
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_name: &'static str,
_index: u32,
variant: &'static str,
value: &T,
) -> Result<()> {
self.open_variant(variant)?;
value.serialize(&mut *self)?;
self.close_variant_wrapper()
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
self.writer.write_all(b"[")?;
if self.pretty {
self.level += 1;
}
Ok(Compound {
ser: self,
first: true,
container: Container::Array,
variant: false,
})
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant> {
self.open_variant(variant)?;
self.writer.write_all(b"[")?;
if self.pretty {
self.level += 1;
}
Ok(Compound {
ser: self,
first: true,
container: Container::Array,
variant: true,
})
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
self.writer.write_all(b"{")?;
if self.pretty {
self.level += 1;
}
Ok(Compound {
ser: self,
first: true,
container: Container::Object,
variant: false,
})
}
fn serialize_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct> {
self.serialize_map(Some(len))
}
fn serialize_struct_variant(
self,
_name: &'static str,
_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant> {
self.open_variant(variant)?;
self.writer.write_all(b"{")?;
if self.pretty {
self.level += 1;
}
Ok(Compound {
ser: self,
first: true,
container: Container::Object,
variant: true,
})
}
}
impl<'a, W: Write> ser::SerializeSeq for Compound<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
self.item()?;
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<()> {
self.finish()
}
}
impl<'a, W: Write> ser::SerializeTuple for Compound<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<()> {
self.finish()
}
}
impl<'a, W: Write> ser::SerializeTupleStruct for Compound<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<()> {
self.finish()
}
}
impl<'a, W: Write> ser::SerializeTupleVariant for Compound<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<()> {
self.finish()
}
}
impl<'a, W: Write> ser::SerializeMap for Compound<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<()> {
self.item()?;
key.serialize(MapKeySerializer { ser: self.ser })
}
fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
self.ser.write_colon()?;
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<()> {
self.finish()
}
}
impl<'a, W: Write> ser::SerializeStruct for Compound<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(
&mut self,
key: &'static str,
value: &T,
) -> Result<()> {
self.item()?;
self.ser.write_key(key)?;
self.ser.write_colon()?;
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<()> {
self.finish()
}
}
impl<'a, W: Write> ser::SerializeStructVariant for Compound<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(
&mut self,
key: &'static str,
value: &T,
) -> Result<()> {
ser::SerializeStruct::serialize_field(self, key, value)
}
fn end(self) -> Result<()> {
self.finish()
}
}
struct BareInt<'a, W> {
writer: &'a mut W,
}
macro_rules! bare_int {
($method:ident, $ty:ty, $cast:ty, $fmt:ident) => {
fn $method(self, value: $ty) -> Result<()> {
let mut buf = [0u8; crate::number::INT_BUF];
let n = crate::number::$fmt(value as $cast, &mut buf);
self.writer.write_all(&buf[..n])?;
Ok(())
}
};
}
impl<'a, W: Write> ser::Serializer for BareInt<'a, W> {
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>;
bare_int!(serialize_i8, i8, i64, fmt_i64);
bare_int!(serialize_i16, i16, i64, fmt_i64);
bare_int!(serialize_i32, i32, i64, fmt_i64);
bare_int!(serialize_i64, i64, i64, fmt_i64);
bare_int!(serialize_u8, u8, u64, fmt_u64);
bare_int!(serialize_u16, u16, u64, fmt_u64);
bare_int!(serialize_u32, u32, u64, fmt_u64);
bare_int!(serialize_u64, u64, u64, fmt_u64);
fn serialize_i128(self, value: i128) -> Result<()> {
write!(self.writer, "{value}")?;
Ok(())
}
fn serialize_u128(self, value: u128) -> Result<()> {
write!(self.writer, "{value}")?;
Ok(())
}
fn serialize_bool(self, _: bool) -> Result<()> {
Err(bare_int_error())
}
fn serialize_f32(self, _: f32) -> Result<()> {
Err(bare_int_error())
}
fn serialize_f64(self, _: f64) -> Result<()> {
Err(bare_int_error())
}
fn serialize_char(self, _: char) -> Result<()> {
Err(bare_int_error())
}
fn serialize_str(self, _: &str) -> Result<()> {
Err(bare_int_error())
}
fn serialize_bytes(self, _: &[u8]) -> Result<()> {
Err(bare_int_error())
}
fn serialize_none(self) -> Result<()> {
Err(bare_int_error())
}
fn serialize_some<T: ?Sized + Serialize>(self, _: &T) -> Result<()> {
Err(bare_int_error())
}
fn serialize_unit(self) -> Result<()> {
Err(bare_int_error())
}
fn serialize_unit_struct(self, _: &'static str) -> Result<()> {
Err(bare_int_error())
}
fn serialize_unit_variant(self, _: &'static str, _: u32, _: &'static str) -> Result<()> {
Err(bare_int_error())
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(
self,
_: &'static str,
value: &T,
) -> Result<()> {
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_: &'static str,
_: u32,
_: &'static str,
_: &T,
) -> Result<()> {
Err(bare_int_error())
}
fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
Err(bare_int_error())
}
fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
Err(bare_int_error())
}
fn serialize_tuple_struct(
self,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleStruct> {
Err(bare_int_error())
}
fn serialize_tuple_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleVariant> {
Err(bare_int_error())
}
fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap> {
Err(bare_int_error())
}
fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct> {
Err(bare_int_error())
}
fn serialize_struct_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeStructVariant> {
Err(bare_int_error())
}
}
fn bare_int_error() -> Error {
Error::message("int(...)/uint(...) payload must be an integer")
}
struct CtorEmitter<'a, W> {
ser: &'a mut Serializer<W>,
}
impl<'a, W: Write> ser::Serializer for CtorEmitter<'a, W> {
type Ok = ();
type Error = Error;
type SerializeSeq = Impossible<(), Error>;
type SerializeTuple = Impossible<(), Error>;
type SerializeTupleStruct = Impossible<(), Error>;
type SerializeTupleVariant = Impossible<(), Error>;
type SerializeMap = CtorCompound<'a, W>;
type SerializeStruct = Impossible<(), Error>;
type SerializeStructVariant = Impossible<(), Error>;
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
Ok(CtorCompound { ser: self.ser })
}
fn serialize_bool(self, _: bool) -> Result<()> {
Err(ctor_error())
}
fn serialize_i8(self, _: i8) -> Result<()> {
Err(ctor_error())
}
fn serialize_i16(self, _: i16) -> Result<()> {
Err(ctor_error())
}
fn serialize_i32(self, _: i32) -> Result<()> {
Err(ctor_error())
}
fn serialize_i64(self, _: i64) -> Result<()> {
Err(ctor_error())
}
fn serialize_i128(self, _: i128) -> Result<()> {
Err(ctor_error())
}
fn serialize_u8(self, _: u8) -> Result<()> {
Err(ctor_error())
}
fn serialize_u16(self, _: u16) -> Result<()> {
Err(ctor_error())
}
fn serialize_u32(self, _: u32) -> Result<()> {
Err(ctor_error())
}
fn serialize_u64(self, _: u64) -> Result<()> {
Err(ctor_error())
}
fn serialize_u128(self, _: u128) -> Result<()> {
Err(ctor_error())
}
fn serialize_f32(self, _: f32) -> Result<()> {
Err(ctor_error())
}
fn serialize_f64(self, _: f64) -> Result<()> {
Err(ctor_error())
}
fn serialize_char(self, _: char) -> Result<()> {
Err(ctor_error())
}
fn serialize_str(self, _: &str) -> Result<()> {
Err(ctor_error())
}
fn serialize_bytes(self, _: &[u8]) -> Result<()> {
Err(ctor_error())
}
fn serialize_none(self) -> Result<()> {
Err(ctor_error())
}
fn serialize_some<T: ?Sized + Serialize>(self, _: &T) -> Result<()> {
Err(ctor_error())
}
fn serialize_unit(self) -> Result<()> {
Err(ctor_error())
}
fn serialize_unit_struct(self, _: &'static str) -> Result<()> {
Err(ctor_error())
}
fn serialize_unit_variant(self, _: &'static str, _: u32, _: &'static str) -> Result<()> {
Err(ctor_error())
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(
self,
_: &'static str,
_: &T,
) -> Result<()> {
Err(ctor_error())
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_: &'static str,
_: u32,
_: &'static str,
_: &T,
) -> Result<()> {
Err(ctor_error())
}
fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
Err(ctor_error())
}
fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
Err(ctor_error())
}
fn serialize_tuple_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeTupleStruct> {
Err(ctor_error())
}
fn serialize_tuple_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleVariant> {
Err(ctor_error())
}
fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct> {
Err(ctor_error())
}
fn serialize_struct_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeStructVariant> {
Err(ctor_error())
}
}
struct CtorCompound<'a, W> {
ser: &'a mut Serializer<W>,
}
impl<'a, W: Write> ser::SerializeMap for CtorCompound<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<()> {
key.serialize(CtorNameSerializer { ser: self.ser })
}
fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
self.ser.writer.write_all(b"(")?;
value.serialize(&mut *self.ser)?;
self.ser.writer.write_all(b")")?;
Ok(())
}
fn end(self) -> Result<()> {
Ok(())
}
}
fn ctor_error() -> Error {
Error::message("a constructor value must serialize as a single name/argument entry")
}
fn ctor_name_error(name: &str) -> Error {
Error::message(format!(
"constructor name {name:?} is not a valid JSONX identifier \
(a leading letter or '_', then letters, digits, or '_'); \
it cannot be serialized to round-trippable JSONX"
))
}
struct CtorNameSerializer<'a, W> {
ser: &'a mut Serializer<W>,
}
impl<'a, W: Write> ser::Serializer for CtorNameSerializer<'a, W> {
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>;
fn serialize_str(self, value: &str) -> Result<()> {
if crate::tokens::is_ident(value) {
self.ser.writer.write_all(value.as_bytes())?;
Ok(())
} else {
Err(ctor_name_error(value))
}
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(
self,
_name: &'static str,
value: &T,
) -> Result<()> {
value.serialize(self)
}
fn serialize_bool(self, _: bool) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_i8(self, _: i8) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_i16(self, _: i16) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_i32(self, _: i32) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_i64(self, _: i64) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_i128(self, _: i128) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_u8(self, _: u8) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_u16(self, _: u16) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_u32(self, _: u32) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_u64(self, _: u64) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_u128(self, _: u128) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_f32(self, _: f32) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_f64(self, _: f64) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_char(self, _: char) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_bytes(self, _: &[u8]) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_none(self) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_some<T: ?Sized + Serialize>(self, _: &T) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_unit(self) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_unit_struct(self, _: &'static str) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_unit_variant(self, _: &'static str, _: u32, _: &'static str) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_: &'static str,
_: u32,
_: &'static str,
_: &T,
) -> Result<()> {
Err(ctor_name_type_error())
}
fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
Err(ctor_name_type_error())
}
fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
Err(ctor_name_type_error())
}
fn serialize_tuple_struct(
self,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleStruct> {
Err(ctor_name_type_error())
}
fn serialize_tuple_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleVariant> {
Err(ctor_name_type_error())
}
fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap> {
Err(ctor_name_type_error())
}
fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct> {
Err(ctor_name_type_error())
}
fn serialize_struct_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeStructVariant> {
Err(ctor_name_type_error())
}
}
fn ctor_name_type_error() -> Error {
Error::message("a constructor name must be an identifier string")
}
struct MapKeySerializer<'a, W> {
ser: &'a mut Serializer<W>,
}
macro_rules! key_from_display {
($method:ident, $ty:ty) => {
fn $method(self, value: $ty) -> Result<()> {
self.ser.write_key(&value.to_string())?;
Ok(())
}
};
}
impl<'a, W: Write> ser::Serializer for MapKeySerializer<'a, W> {
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>;
fn serialize_str(self, value: &str) -> Result<()> {
self.ser.write_key(value)?;
Ok(())
}
fn serialize_char(self, value: char) -> Result<()> {
let mut buf = [0u8; 4];
self.ser.write_key(value.encode_utf8(&mut buf))?;
Ok(())
}
key_from_display!(serialize_i8, i8);
key_from_display!(serialize_i16, i16);
key_from_display!(serialize_i32, i32);
key_from_display!(serialize_i64, i64);
key_from_display!(serialize_i128, i128);
key_from_display!(serialize_u8, u8);
key_from_display!(serialize_u16, u16);
key_from_display!(serialize_u32, u32);
key_from_display!(serialize_u64, u64);
key_from_display!(serialize_u128, u128);
key_from_display!(serialize_bool, bool);
fn serialize_newtype_struct<T: ?Sized + Serialize>(
self,
_name: &'static str,
value: &T,
) -> Result<()> {
value.serialize(self)
}
fn serialize_unit_variant(
self,
_name: &'static str,
_index: u32,
variant: &'static str,
) -> Result<()> {
self.ser.write_key(variant)?;
Ok(())
}
fn serialize_f32(self, _: f32) -> Result<()> {
Err(key_error())
}
fn serialize_f64(self, _: f64) -> Result<()> {
Err(key_error())
}
fn serialize_bytes(self, _: &[u8]) -> Result<()> {
Err(key_error())
}
fn serialize_none(self) -> Result<()> {
Err(key_error())
}
fn serialize_some<T: ?Sized + Serialize>(self, _: &T) -> Result<()> {
Err(key_error())
}
fn serialize_unit(self) -> Result<()> {
Err(key_error())
}
fn serialize_unit_struct(self, _: &'static str) -> Result<()> {
Err(key_error())
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_: &'static str,
_: u32,
_: &'static str,
_: &T,
) -> Result<()> {
Err(key_error())
}
fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
Err(key_error())
}
fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
Err(key_error())
}
fn serialize_tuple_struct(
self,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleStruct> {
Err(key_error())
}
fn serialize_tuple_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleVariant> {
Err(key_error())
}
fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap> {
Err(key_error())
}
fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct> {
Err(key_error())
}
fn serialize_struct_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeStructVariant> {
Err(key_error())
}
}
fn key_error() -> Error {
Error::message("object keys must be strings (or stringifiable scalars)")
}