use std::fmt::Write as _;
use serde::ser::{
self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
SerializeTuple, SerializeTupleStruct, SerializeTupleVariant,
};
use crate::error::{Error, Result};
const INDENT: &str = " ";
pub fn to_string<T: ?Sized + Serialize>(value: &T) -> Result<String> {
let mut out = String::with_capacity(2048);
value.serialize(RootSer { out: &mut out })?;
Ok(out)
}
fn write_indent(out: &mut String, level: usize) {
const SPACES: &str = " "; let mut remaining = level * INDENT.len();
if remaining == 0 {
return;
}
out.reserve(remaining);
while remaining > 0 {
let chunk = remaining.min(SPACES.len());
out.push_str(&SPACES[..chunk]);
remaining -= chunk;
}
}
fn needs_raw_marker(s: &str) -> bool {
match s.as_bytes().first() {
None => false,
Some(&b' ') | Some(&b'\t') => needs_raw_marker_slow(s.trim_start()),
Some(&b'{') | Some(&b'[') => true,
Some(_) => {
matches!(s, "null" | "true" | "false" | "(" | "((" | "()" | "(())")
}
}
}
#[cold]
#[inline(never)]
fn needs_raw_marker_slow(t: &str) -> bool {
t.starts_with('{')
|| t.starts_with('[')
|| matches!(t, "null" | "true" | "false" | "(" | "((" | "()" | "(())")
}
fn top_err() -> Error {
<Error as ser::Error>::custom("top-level value must be an object")
}
fn key_err() -> Error {
<Error as ser::Error>::custom("map keys must serialize to strings")
}
fn push_float_body(out: &mut String, s: &str) {
let bytes = s.as_bytes();
let mut e_pos: Option<usize> = None;
let mut has_dot = false;
for (i, &b) in bytes.iter().enumerate() {
if b == b'.' {
has_dot = true;
} else if b == b'e' || b == b'E' {
e_pos = Some(i);
break;
}
}
match (e_pos, has_dot) {
(_, true) => out.push_str(s),
(Some(pos), false) => {
out.push_str(&s[..pos]);
out.push_str(".0");
out.push_str(&s[pos..]);
}
(None, false) => {
out.push_str(s);
out.push_str(".0");
}
}
}
pub(crate) fn format_f64(v: f64) -> Result<String> {
if v.is_nan() || v.is_infinite() {
return Err(<Error as ser::Error>::custom(
"NaN / Infinity is not representable in Ktav 0.1.0",
));
}
let mut buf = ryu::Buffer::new();
let mut out = String::with_capacity(24);
push_float_body(&mut out, buf.format(v));
Ok(out)
}
pub(crate) fn format_f32(v: f32) -> Result<String> {
if v.is_nan() || v.is_infinite() {
return Err(<Error as ser::Error>::custom(
"NaN / Infinity is not representable in Ktav 0.1.0",
));
}
let mut buf = ryu::Buffer::new();
let mut out = String::with_capacity(16);
push_float_body(&mut out, buf.format(v));
Ok(out)
}
fn push_int_pair<I: itoa::Integer>(out: &mut String, v: I) {
out.push_str(":i ");
let mut buf = itoa::Buffer::new();
out.push_str(buf.format(v));
out.push('\n');
}
fn push_int_item<I: itoa::Integer>(out: &mut String, v: I) {
out.push_str(":i ");
let mut buf = itoa::Buffer::new();
out.push_str(buf.format(v));
out.push('\n');
}
fn push_f64_pair(out: &mut String, v: f64) -> Result<()> {
if v.is_nan() || v.is_infinite() {
return Err(<Error as ser::Error>::custom(
"NaN / Infinity is not representable in Ktav 0.1.0",
));
}
out.push_str(":f ");
let mut buf = ryu::Buffer::new();
push_float_body(out, buf.format(v));
out.push('\n');
Ok(())
}
fn push_f32_pair(out: &mut String, v: f32) -> Result<()> {
if v.is_nan() || v.is_infinite() {
return Err(<Error as ser::Error>::custom(
"NaN / Infinity is not representable in Ktav 0.1.0",
));
}
out.push_str(":f ");
let mut buf = ryu::Buffer::new();
push_float_body(out, buf.format(v));
out.push('\n');
Ok(())
}
struct RootSer<'a> {
out: &'a mut String,
}
impl<'a> ser::Serializer for RootSer<'a> {
type Ok = ();
type Error = Error;
type SerializeSeq = UnreachableCompound;
type SerializeTuple = UnreachableCompound;
type SerializeTupleStruct = UnreachableCompound;
type SerializeTupleVariant = UnreachableCompound;
type SerializeMap = ObjectCompound<'a>;
type SerializeStruct = ObjectCompound<'a>;
type SerializeStructVariant = UnreachableCompound;
fn serialize_bool(self, _: bool) -> Result<()> {
Err(top_err())
}
fn serialize_i8(self, _: i8) -> Result<()> {
Err(top_err())
}
fn serialize_i16(self, _: i16) -> Result<()> {
Err(top_err())
}
fn serialize_i32(self, _: i32) -> Result<()> {
Err(top_err())
}
fn serialize_i64(self, _: i64) -> Result<()> {
Err(top_err())
}
fn serialize_u8(self, _: u8) -> Result<()> {
Err(top_err())
}
fn serialize_u16(self, _: u16) -> Result<()> {
Err(top_err())
}
fn serialize_u32(self, _: u32) -> Result<()> {
Err(top_err())
}
fn serialize_u64(self, _: u64) -> Result<()> {
Err(top_err())
}
fn serialize_f32(self, _: f32) -> Result<()> {
Err(top_err())
}
fn serialize_f64(self, _: f64) -> Result<()> {
Err(top_err())
}
fn serialize_char(self, _: char) -> Result<()> {
Err(top_err())
}
fn serialize_str(self, _: &str) -> Result<()> {
Err(top_err())
}
fn serialize_bytes(self, _: &[u8]) -> Result<()> {
Err(top_err())
}
fn serialize_none(self) -> Result<()> {
Err(top_err())
}
fn serialize_some<T: ?Sized + Serialize>(self, v: &T) -> Result<()> {
v.serialize(self)
}
fn serialize_unit(self) -> Result<()> {
Err(top_err())
}
fn serialize_unit_struct(self, _: &'static str) -> Result<()> {
Err(top_err())
}
fn serialize_unit_variant(self, _: &'static str, _: u32, _: &'static str) -> Result<()> {
Err(top_err())
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(self, _: &'static str, v: &T) -> Result<()> {
v.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_: &'static str,
_: u32,
_: &'static str,
_: &T,
) -> Result<()> {
Err(top_err())
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
Err(top_err())
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
Err(top_err())
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct> {
Err(top_err())
}
fn serialize_tuple_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleVariant> {
Err(top_err())
}
fn serialize_map(self, _len: Option<usize>) -> Result<ObjectCompound<'a>> {
Ok(ObjectCompound::root(self.out))
}
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<ObjectCompound<'a>> {
Ok(ObjectCompound::root(self.out))
}
fn serialize_struct_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeStructVariant> {
Err(top_err())
}
}
struct ObjectCompound<'a> {
out: &'a mut String,
field_indent: usize,
close: Option<usize>, pending_key: Option<String>, empty_so_far: bool,
}
impl<'a> ObjectCompound<'a> {
fn root(out: &'a mut String) -> Self {
Self {
out,
field_indent: 0,
close: None,
pending_key: None,
empty_so_far: true,
}
}
fn wrapped(out: &'a mut String, field_indent: usize, close_indent: usize) -> Self {
Self {
out,
field_indent,
close: Some(close_indent),
pending_key: None,
empty_so_far: true,
}
}
}
impl<'a> SerializeStruct for ObjectCompound<'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(
&mut self,
key: &'static str,
value: &T,
) -> Result<()> {
self.empty_so_far = false;
write_indent(self.out, self.field_indent);
self.out.push_str(key);
value.serialize(PairValueSer {
out: self.out,
indent: self.field_indent,
})
}
fn end(self) -> Result<()> {
if let Some(outer) = self.close {
write_indent(self.out, outer);
self.out.push_str("}\n");
}
Ok(())
}
}
impl<'a> SerializeMap for ObjectCompound<'a> {
type Ok = ();
type Error = Error;
fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<()> {
let mut buf = String::new();
key.serialize(KeyOnlySer { out: &mut buf })?;
self.pending_key = Some(buf);
Ok(())
}
fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
let key = self.pending_key.take().ok_or_else(|| {
<Error as ser::Error>::custom("serialize_value without preceding key")
})?;
self.empty_so_far = false;
write_indent(self.out, self.field_indent);
self.out.push_str(&key);
value.serialize(PairValueSer {
out: self.out,
indent: self.field_indent,
})
}
fn end(self) -> Result<()> {
if let Some(outer) = self.close {
write_indent(self.out, outer);
self.out.push_str("}\n");
}
Ok(())
}
}
struct KeyOnlySer<'a> {
out: &'a mut String,
}
impl<'a> ser::Serializer for KeyOnlySer<'a> {
type Ok = ();
type Error = Error;
type SerializeSeq = UnreachableCompound;
type SerializeTuple = UnreachableCompound;
type SerializeTupleStruct = UnreachableCompound;
type SerializeTupleVariant = UnreachableCompound;
type SerializeMap = UnreachableCompound;
type SerializeStruct = UnreachableCompound;
type SerializeStructVariant = UnreachableCompound;
fn serialize_str(self, v: &str) -> Result<()> {
self.out.push_str(v);
Ok(())
}
fn serialize_bool(self, v: bool) -> Result<()> {
self.out.push_str(if v { "true" } else { "false" });
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<()> {
write!(self.out, "{v}").map_err(|_| Error::Message("fmt error".into()))
}
fn serialize_i16(self, v: i16) -> Result<()> {
write!(self.out, "{v}").map_err(|_| Error::Message("fmt error".into()))
}
fn serialize_i32(self, v: i32) -> Result<()> {
write!(self.out, "{v}").map_err(|_| Error::Message("fmt error".into()))
}
fn serialize_i64(self, v: i64) -> Result<()> {
write!(self.out, "{v}").map_err(|_| Error::Message("fmt error".into()))
}
fn serialize_u8(self, v: u8) -> Result<()> {
write!(self.out, "{v}").map_err(|_| Error::Message("fmt error".into()))
}
fn serialize_u16(self, v: u16) -> Result<()> {
write!(self.out, "{v}").map_err(|_| Error::Message("fmt error".into()))
}
fn serialize_u32(self, v: u32) -> Result<()> {
write!(self.out, "{v}").map_err(|_| Error::Message("fmt error".into()))
}
fn serialize_u64(self, v: u64) -> Result<()> {
write!(self.out, "{v}").map_err(|_| Error::Message("fmt error".into()))
}
fn serialize_f32(self, v: f32) -> Result<()> {
write!(self.out, "{v}").map_err(|_| Error::Message("fmt error".into()))
}
fn serialize_f64(self, v: f64) -> Result<()> {
write!(self.out, "{v}").map_err(|_| Error::Message("fmt error".into()))
}
fn serialize_char(self, v: char) -> Result<()> {
self.out.push(v);
Ok(())
}
fn serialize_bytes(self, _: &[u8]) -> Result<()> {
Err(key_err())
}
fn serialize_none(self) -> Result<()> {
Err(key_err())
}
fn serialize_some<T: ?Sized + Serialize>(self, v: &T) -> Result<()> {
v.serialize(self)
}
fn serialize_unit(self) -> Result<()> {
Err(key_err())
}
fn serialize_unit_struct(self, _: &'static str) -> Result<()> {
Err(key_err())
}
fn serialize_unit_variant(self, _: &'static str, _: u32, variant: &'static str) -> Result<()> {
self.out.push_str(variant);
Ok(())
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(self, _: &'static str, v: &T) -> Result<()> {
v.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_: &'static str,
_: u32,
_: &'static str,
_: &T,
) -> Result<()> {
Err(key_err())
}
fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
Err(key_err())
}
fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
Err(key_err())
}
fn serialize_tuple_struct(
self,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleStruct> {
Err(key_err())
}
fn serialize_tuple_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleVariant> {
Err(key_err())
}
fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap> {
Err(key_err())
}
fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct> {
Err(key_err())
}
fn serialize_struct_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeStructVariant> {
Err(key_err())
}
}
struct PairValueSer<'a> {
out: &'a mut String,
indent: usize, }
impl<'a> PairValueSer<'a> {
fn write_scalar_line(self, v: &str) {
if v.contains('\n') {
self.out.push_str(": ((\n");
self.out.push_str(v);
self.out.push('\n');
write_indent(self.out, self.indent);
self.out.push_str("))\n");
} else if needs_raw_marker(v) {
self.out.push_str(":: ");
self.out.push_str(v);
self.out.push('\n');
} else {
self.out.push_str(": ");
self.out.push_str(v);
self.out.push('\n');
}
}
}
impl<'a> ser::Serializer for PairValueSer<'a> {
type Ok = ();
type Error = Error;
type SerializeSeq = SeqCompound<'a>;
type SerializeTuple = SeqCompound<'a>;
type SerializeTupleStruct = SeqCompound<'a>;
type SerializeTupleVariant = TupleVariantPair<'a>;
type SerializeMap = ObjectCompound<'a>;
type SerializeStruct = ObjectCompound<'a>;
type SerializeStructVariant = StructVariantPair<'a>;
fn serialize_bool(self, v: bool) -> Result<()> {
self.out.push_str(": ");
self.out.push_str(if v { "true" } else { "false" });
self.out.push('\n');
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<()> {
push_int_pair(self.out, v);
Ok(())
}
fn serialize_i16(self, v: i16) -> Result<()> {
push_int_pair(self.out, v);
Ok(())
}
fn serialize_i32(self, v: i32) -> Result<()> {
push_int_pair(self.out, v);
Ok(())
}
fn serialize_i64(self, v: i64) -> Result<()> {
push_int_pair(self.out, v);
Ok(())
}
fn serialize_i128(self, v: i128) -> Result<()> {
push_int_pair(self.out, v);
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<()> {
push_int_pair(self.out, v);
Ok(())
}
fn serialize_u16(self, v: u16) -> Result<()> {
push_int_pair(self.out, v);
Ok(())
}
fn serialize_u32(self, v: u32) -> Result<()> {
push_int_pair(self.out, v);
Ok(())
}
fn serialize_u64(self, v: u64) -> Result<()> {
push_int_pair(self.out, v);
Ok(())
}
fn serialize_u128(self, v: u128) -> Result<()> {
push_int_pair(self.out, v);
Ok(())
}
fn serialize_f32(self, v: f32) -> Result<()> {
push_f32_pair(self.out, v)
}
fn serialize_f64(self, v: f64) -> Result<()> {
push_f64_pair(self.out, v)
}
fn serialize_char(self, v: char) -> Result<()> {
let s = v.to_string();
self.write_scalar_line(&s);
Ok(())
}
fn serialize_str(self, v: &str) -> Result<()> {
self.write_scalar_line(v);
Ok(())
}
fn serialize_bytes(self, v: &[u8]) -> Result<()> {
self.out.push_str(": ");
if v.is_empty() {
self.out.push_str("[]\n");
} else {
self.out.push_str("[\n");
for &b in v {
write_indent(self.out, self.indent + 1);
push_int_item(self.out, b);
}
write_indent(self.out, self.indent);
self.out.push_str("]\n");
}
Ok(())
}
fn serialize_none(self) -> Result<()> {
self.out.push_str(": null\n");
Ok(())
}
fn serialize_some<T: ?Sized + Serialize>(self, v: &T) -> Result<()> {
v.serialize(self)
}
fn serialize_unit(self) -> Result<()> {
self.out.push_str(": null\n");
Ok(())
}
fn serialize_unit_struct(self, _: &'static str) -> Result<()> {
self.out.push_str(": null\n");
Ok(())
}
fn serialize_unit_variant(self, _: &'static str, _: u32, variant: &'static str) -> Result<()> {
self.write_scalar_line(variant);
Ok(())
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(self, _: &'static str, v: &T) -> Result<()> {
v.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_: &'static str,
_: u32,
variant: &'static str,
value: &T,
) -> Result<()> {
self.out.push_str(": {\n");
write_indent(self.out, self.indent + 1);
self.out.push_str(variant);
value.serialize(PairValueSer {
out: self.out,
indent: self.indent + 1,
})?;
write_indent(self.out, self.indent);
self.out.push_str("}\n");
Ok(())
}
fn serialize_seq(self, len: Option<usize>) -> Result<SeqCompound<'a>> {
if let Some(0) = len {
self.out.push_str(": []\n");
return Ok(SeqCompound::closed(self.out));
}
self.out.push_str(": [\n");
Ok(SeqCompound::wrapped(self.out, self.indent + 1, self.indent))
}
fn serialize_tuple(self, len: usize) -> Result<SeqCompound<'a>> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct(self, _: &'static str, len: usize) -> Result<SeqCompound<'a>> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(
self,
_: &'static str,
_: u32,
variant: &'static str,
_len: usize,
) -> Result<TupleVariantPair<'a>> {
self.out.push_str(": {\n");
write_indent(self.out, self.indent + 1);
self.out.push_str(variant);
self.out.push_str(": [\n");
Ok(TupleVariantPair {
out: self.out,
outer_indent: self.indent,
variant_indent: self.indent + 1,
item_indent: self.indent + 2,
})
}
fn serialize_map(self, len: Option<usize>) -> Result<ObjectCompound<'a>> {
if let Some(0) = len {
self.out.push_str(": {}\n");
return Ok(ObjectCompound::closed(self.out));
}
self.out.push_str(": {\n");
Ok(ObjectCompound::wrapped(
self.out,
self.indent + 1,
self.indent,
))
}
fn serialize_struct(self, _: &'static str, len: usize) -> Result<ObjectCompound<'a>> {
if len == 0 {
self.out.push_str(": {}\n");
return Ok(ObjectCompound::closed(self.out));
}
self.out.push_str(": {\n");
Ok(ObjectCompound::wrapped(
self.out,
self.indent + 1,
self.indent,
))
}
fn serialize_struct_variant(
self,
_: &'static str,
_: u32,
variant: &'static str,
_: usize,
) -> Result<StructVariantPair<'a>> {
self.out.push_str(": {\n");
write_indent(self.out, self.indent + 1);
self.out.push_str(variant);
self.out.push_str(": {\n");
Ok(StructVariantPair {
out: self.out,
outer_indent: self.indent,
variant_indent: self.indent + 1,
field_indent: self.indent + 2,
})
}
}
impl<'a> ObjectCompound<'a> {
fn closed(out: &'a mut String) -> Self {
Self {
out,
field_indent: 0,
close: None,
pending_key: None,
empty_so_far: true,
}
}
}
struct ItemValueSer<'a> {
out: &'a mut String,
indent: usize,
}
impl<'a> ItemValueSer<'a> {
fn write_scalar_line(self, v: &str) {
write_indent(self.out, self.indent);
if v.contains('\n') {
self.out.push_str("((\n");
self.out.push_str(v);
self.out.push('\n');
write_indent(self.out, self.indent);
self.out.push_str("))\n");
} else if v.is_empty() {
self.out.push_str("::\n");
} else if needs_raw_marker(v) {
self.out.push_str(":: ");
self.out.push_str(v);
self.out.push('\n');
} else {
self.out.push_str(v);
self.out.push('\n');
}
}
}
impl<'a> ser::Serializer for ItemValueSer<'a> {
type Ok = ();
type Error = Error;
type SerializeSeq = SeqCompound<'a>;
type SerializeTuple = SeqCompound<'a>;
type SerializeTupleStruct = SeqCompound<'a>;
type SerializeTupleVariant = TupleVariantItem<'a>;
type SerializeMap = ObjectCompound<'a>;
type SerializeStruct = ObjectCompound<'a>;
type SerializeStructVariant = StructVariantItem<'a>;
fn serialize_bool(self, v: bool) -> Result<()> {
write_indent(self.out, self.indent);
self.out.push_str(if v { "true" } else { "false" });
self.out.push('\n');
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<()> {
write_indent(self.out, self.indent);
push_int_item(self.out, v);
Ok(())
}
fn serialize_i16(self, v: i16) -> Result<()> {
write_indent(self.out, self.indent);
push_int_item(self.out, v);
Ok(())
}
fn serialize_i32(self, v: i32) -> Result<()> {
write_indent(self.out, self.indent);
push_int_item(self.out, v);
Ok(())
}
fn serialize_i64(self, v: i64) -> Result<()> {
write_indent(self.out, self.indent);
push_int_item(self.out, v);
Ok(())
}
fn serialize_i128(self, v: i128) -> Result<()> {
write_indent(self.out, self.indent);
push_int_item(self.out, v);
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<()> {
write_indent(self.out, self.indent);
push_int_item(self.out, v);
Ok(())
}
fn serialize_u16(self, v: u16) -> Result<()> {
write_indent(self.out, self.indent);
push_int_item(self.out, v);
Ok(())
}
fn serialize_u32(self, v: u32) -> Result<()> {
write_indent(self.out, self.indent);
push_int_item(self.out, v);
Ok(())
}
fn serialize_u64(self, v: u64) -> Result<()> {
write_indent(self.out, self.indent);
push_int_item(self.out, v);
Ok(())
}
fn serialize_u128(self, v: u128) -> Result<()> {
write_indent(self.out, self.indent);
push_int_item(self.out, v);
Ok(())
}
fn serialize_f32(self, v: f32) -> Result<()> {
write_indent(self.out, self.indent);
push_f32_pair(self.out, v)
}
fn serialize_f64(self, v: f64) -> Result<()> {
write_indent(self.out, self.indent);
push_f64_pair(self.out, v)
}
fn serialize_char(self, v: char) -> Result<()> {
let s = v.to_string();
self.write_scalar_line(&s);
Ok(())
}
fn serialize_str(self, v: &str) -> Result<()> {
self.write_scalar_line(v);
Ok(())
}
fn serialize_bytes(self, v: &[u8]) -> Result<()> {
write_indent(self.out, self.indent);
if v.is_empty() {
self.out.push_str("[]\n");
} else {
self.out.push_str("[\n");
for &b in v {
write_indent(self.out, self.indent + 1);
push_int_item(self.out, b);
}
write_indent(self.out, self.indent);
self.out.push_str("]\n");
}
Ok(())
}
fn serialize_none(self) -> Result<()> {
write_indent(self.out, self.indent);
self.out.push_str("null\n");
Ok(())
}
fn serialize_some<T: ?Sized + Serialize>(self, v: &T) -> Result<()> {
v.serialize(self)
}
fn serialize_unit(self) -> Result<()> {
write_indent(self.out, self.indent);
self.out.push_str("null\n");
Ok(())
}
fn serialize_unit_struct(self, _: &'static str) -> Result<()> {
self.serialize_unit()
}
fn serialize_unit_variant(self, _: &'static str, _: u32, variant: &'static str) -> Result<()> {
self.write_scalar_line(variant);
Ok(())
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(self, _: &'static str, v: &T) -> Result<()> {
v.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
_: &'static str,
_: u32,
variant: &'static str,
value: &T,
) -> Result<()> {
write_indent(self.out, self.indent);
self.out.push_str("{\n");
write_indent(self.out, self.indent + 1);
self.out.push_str(variant);
value.serialize(PairValueSer {
out: self.out,
indent: self.indent + 1,
})?;
write_indent(self.out, self.indent);
self.out.push_str("}\n");
Ok(())
}
fn serialize_seq(self, len: Option<usize>) -> Result<SeqCompound<'a>> {
write_indent(self.out, self.indent);
if let Some(0) = len {
self.out.push_str("[]\n");
return Ok(SeqCompound::closed(self.out));
}
self.out.push_str("[\n");
Ok(SeqCompound::wrapped(self.out, self.indent + 1, self.indent))
}
fn serialize_tuple(self, len: usize) -> Result<SeqCompound<'a>> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct(self, _: &'static str, len: usize) -> Result<SeqCompound<'a>> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(
self,
_: &'static str,
_: u32,
variant: &'static str,
_len: usize,
) -> Result<TupleVariantItem<'a>> {
write_indent(self.out, self.indent);
self.out.push_str("{\n");
write_indent(self.out, self.indent + 1);
self.out.push_str(variant);
self.out.push_str(": [\n");
Ok(TupleVariantItem {
out: self.out,
outer_indent: self.indent,
variant_indent: self.indent + 1,
item_indent: self.indent + 2,
})
}
fn serialize_map(self, len: Option<usize>) -> Result<ObjectCompound<'a>> {
write_indent(self.out, self.indent);
if let Some(0) = len {
self.out.push_str("{}\n");
return Ok(ObjectCompound::closed(self.out));
}
self.out.push_str("{\n");
Ok(ObjectCompound::wrapped(
self.out,
self.indent + 1,
self.indent,
))
}
fn serialize_struct(self, _: &'static str, len: usize) -> Result<ObjectCompound<'a>> {
write_indent(self.out, self.indent);
if len == 0 {
self.out.push_str("{}\n");
return Ok(ObjectCompound::closed(self.out));
}
self.out.push_str("{\n");
Ok(ObjectCompound::wrapped(
self.out,
self.indent + 1,
self.indent,
))
}
fn serialize_struct_variant(
self,
_: &'static str,
_: u32,
variant: &'static str,
_: usize,
) -> Result<StructVariantItem<'a>> {
write_indent(self.out, self.indent);
self.out.push_str("{\n");
write_indent(self.out, self.indent + 1);
self.out.push_str(variant);
self.out.push_str(": {\n");
Ok(StructVariantItem {
out: self.out,
outer_indent: self.indent,
variant_indent: self.indent + 1,
field_indent: self.indent + 2,
})
}
}
struct SeqCompound<'a> {
out: &'a mut String,
item_indent: usize,
close: Option<usize>, }
impl<'a> SeqCompound<'a> {
fn wrapped(out: &'a mut String, item_indent: usize, close_indent: usize) -> Self {
Self {
out,
item_indent,
close: Some(close_indent),
}
}
fn closed(out: &'a mut String) -> Self {
Self {
out,
item_indent: 0,
close: None,
}
}
}
impl<'a> SerializeSeq for SeqCompound<'a> {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized + Serialize>(&mut self, v: &T) -> Result<()> {
v.serialize(ItemValueSer {
out: self.out,
indent: self.item_indent,
})
}
fn end(self) -> Result<()> {
if let Some(outer) = self.close {
write_indent(self.out, outer);
self.out.push_str("]\n");
}
Ok(())
}
}
impl<'a> SerializeTuple for SeqCompound<'a> {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized + Serialize>(&mut self, v: &T) -> Result<()> {
<Self as SerializeSeq>::serialize_element(self, v)
}
fn end(self) -> Result<()> {
<Self as SerializeSeq>::end(self)
}
}
impl<'a> SerializeTupleStruct for SeqCompound<'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, v: &T) -> Result<()> {
<Self as SerializeSeq>::serialize_element(self, v)
}
fn end(self) -> Result<()> {
<Self as SerializeSeq>::end(self)
}
}
struct TupleVariantPair<'a> {
out: &'a mut String,
outer_indent: usize,
variant_indent: usize,
item_indent: usize,
}
impl<'a> SerializeTupleVariant for TupleVariantPair<'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, v: &T) -> Result<()> {
v.serialize(ItemValueSer {
out: self.out,
indent: self.item_indent,
})
}
fn end(self) -> Result<()> {
write_indent(self.out, self.variant_indent);
self.out.push_str("]\n");
write_indent(self.out, self.outer_indent);
self.out.push_str("}\n");
Ok(())
}
}
struct TupleVariantItem<'a> {
out: &'a mut String,
outer_indent: usize,
variant_indent: usize,
item_indent: usize,
}
impl<'a> SerializeTupleVariant for TupleVariantItem<'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, v: &T) -> Result<()> {
v.serialize(ItemValueSer {
out: self.out,
indent: self.item_indent,
})
}
fn end(self) -> Result<()> {
write_indent(self.out, self.variant_indent);
self.out.push_str("]\n");
write_indent(self.out, self.outer_indent);
self.out.push_str("}\n");
Ok(())
}
}
struct StructVariantPair<'a> {
out: &'a mut String,
outer_indent: usize,
variant_indent: usize,
field_indent: usize,
}
impl<'a> SerializeStructVariant for StructVariantPair<'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(
&mut self,
name: &'static str,
value: &T,
) -> Result<()> {
write_indent(self.out, self.field_indent);
self.out.push_str(name);
value.serialize(PairValueSer {
out: self.out,
indent: self.field_indent,
})
}
fn end(self) -> Result<()> {
write_indent(self.out, self.variant_indent);
self.out.push_str("}\n");
write_indent(self.out, self.outer_indent);
self.out.push_str("}\n");
Ok(())
}
}
struct StructVariantItem<'a> {
out: &'a mut String,
outer_indent: usize,
variant_indent: usize,
field_indent: usize,
}
impl<'a> SerializeStructVariant for StructVariantItem<'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(
&mut self,
name: &'static str,
value: &T,
) -> Result<()> {
write_indent(self.out, self.field_indent);
self.out.push_str(name);
value.serialize(PairValueSer {
out: self.out,
indent: self.field_indent,
})
}
fn end(self) -> Result<()> {
write_indent(self.out, self.variant_indent);
self.out.push_str("}\n");
write_indent(self.out, self.outer_indent);
self.out.push_str("}\n");
Ok(())
}
}
struct UnreachableCompound;
impl SerializeSeq for UnreachableCompound {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized + Serialize>(&mut self, _: &T) -> Result<()> {
unreachable!()
}
fn end(self) -> Result<()> {
unreachable!()
}
}
impl SerializeTuple for UnreachableCompound {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized + Serialize>(&mut self, _: &T) -> Result<()> {
unreachable!()
}
fn end(self) -> Result<()> {
unreachable!()
}
}
impl SerializeTupleStruct for UnreachableCompound {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, _: &T) -> Result<()> {
unreachable!()
}
fn end(self) -> Result<()> {
unreachable!()
}
}
impl SerializeTupleVariant for UnreachableCompound {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, _: &T) -> Result<()> {
unreachable!()
}
fn end(self) -> Result<()> {
unreachable!()
}
}
impl SerializeMap for UnreachableCompound {
type Ok = ();
type Error = Error;
fn serialize_key<T: ?Sized + Serialize>(&mut self, _: &T) -> Result<()> {
unreachable!()
}
fn serialize_value<T: ?Sized + Serialize>(&mut self, _: &T) -> Result<()> {
unreachable!()
}
fn end(self) -> Result<()> {
unreachable!()
}
}
impl SerializeStruct for UnreachableCompound {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, _: &'static str, _: &T) -> Result<()> {
unreachable!()
}
fn end(self) -> Result<()> {
unreachable!()
}
}
impl SerializeStructVariant for UnreachableCompound {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, _: &'static str, _: &T) -> Result<()> {
unreachable!()
}
fn end(self) -> Result<()> {
unreachable!()
}
}