Merge pull request 'Implement generic writer target' (#12) from feat/to-writer into master
* feat/to-writer: Implement generic writer target
This commit is contained in:
commit
609c711e3f
5 changed files with 176 additions and 131 deletions
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
=== Added
|
=== Added
|
||||||
|
|
||||||
|
- implement serializing into generic `io::Write`
|
||||||
|
|
||||||
=== Fixed
|
=== Fixed
|
||||||
|
|
||||||
- fix parsing CRLF
|
- fix parsing CRLF
|
||||||
|
|
10
src/error.rs
10
src/error.rs
|
@ -1,4 +1,4 @@
|
||||||
use std::fmt;
|
use std::{fmt, io};
|
||||||
|
|
||||||
use crate::parser::Token;
|
use crate::parser::Token;
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ pub(crate) enum ErrorCode {
|
||||||
ExpectedTopLevelObject,
|
ExpectedTopLevelObject,
|
||||||
ExpectedValue,
|
ExpectedValue,
|
||||||
TrailingCharacters,
|
TrailingCharacters,
|
||||||
|
NonFiniteFloat,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ErrorCode {
|
impl fmt::Display for ErrorCode {
|
||||||
|
@ -64,6 +65,7 @@ impl fmt::Display for ErrorCode {
|
||||||
ErrorCode::ExpectedTopLevelObject => f.write_str("expected object at the top level"),
|
ErrorCode::ExpectedTopLevelObject => f.write_str("expected object at the top level"),
|
||||||
ErrorCode::ExpectedValue => f.write_str("expected a value"),
|
ErrorCode::ExpectedValue => f.write_str("expected a value"),
|
||||||
ErrorCode::TrailingCharacters => f.write_str("unexpected trailing characters"),
|
ErrorCode::TrailingCharacters => f.write_str("unexpected trailing characters"),
|
||||||
|
ErrorCode::NonFiniteFloat => f.write_str("got infinite floating point number"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,3 +168,9 @@ impl Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for Error {
|
||||||
|
fn from(err: io::Error) -> Self {
|
||||||
|
Self::new(ErrorCode::Message(format!("{}", err)), 0, 0, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,4 +5,4 @@ mod ser;
|
||||||
|
|
||||||
pub use de::{from_str, Deserializer};
|
pub use de::{from_str, Deserializer};
|
||||||
pub use error::{Error, Result};
|
pub use error::{Error, Result};
|
||||||
pub use ser::{to_string, Serializer};
|
pub use ser::{to_string, to_vec, to_writer, Serializer};
|
||||||
|
|
284
src/ser.rs
284
src/ser.rs
|
@ -1,36 +1,75 @@
|
||||||
|
use std::io;
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::error::{Error, ErrorCode, Result};
|
use crate::error::{Error, ErrorCode, Result};
|
||||||
|
|
||||||
// TODO: Make configurable
|
// TODO: Make configurable
|
||||||
const INDENT: &str = " ";
|
const INDENT: [u8; 2] = [0x20, 0x20];
|
||||||
|
|
||||||
pub struct Serializer {
|
pub struct Serializer<W> {
|
||||||
// The current indentation level
|
// The current indentation level
|
||||||
level: usize,
|
level: usize,
|
||||||
// The output string
|
writer: W,
|
||||||
output: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn to_writer<T, W>(writer: &mut W, value: &T) -> Result<()>
|
||||||
|
where
|
||||||
|
W: io::Write,
|
||||||
|
T: Serialize,
|
||||||
|
{
|
||||||
|
let mut serializer = Serializer::new(writer);
|
||||||
|
value.serialize(&mut serializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
|
||||||
|
where
|
||||||
|
T: Serialize,
|
||||||
|
{
|
||||||
|
let mut vec = Vec::with_capacity(128);
|
||||||
|
to_writer(&mut vec, value)?;
|
||||||
|
Ok(vec)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn to_string<T>(value: &T) -> Result<String>
|
pub fn to_string<T>(value: &T) -> Result<String>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let mut serializer = Serializer {
|
let vec = to_vec(value)?;
|
||||||
level: 0,
|
let string = if cfg!(debug_assertions) {
|
||||||
output: String::new(),
|
String::from_utf8(vec).expect("We do not emit invalid UTF-8")
|
||||||
|
} else {
|
||||||
|
unsafe { String::from_utf8_unchecked(vec) }
|
||||||
};
|
};
|
||||||
value.serialize(&mut serializer)?;
|
Ok(string)
|
||||||
Ok(serializer.output)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serializer {
|
impl<W> Serializer<W>
|
||||||
fn add_indent(&mut self) {
|
where
|
||||||
for _ in 0..self.level.saturating_sub(1) {
|
W: io::Write,
|
||||||
self.output += INDENT;
|
{
|
||||||
}
|
pub fn new(writer: W) -> Self {
|
||||||
|
Self { level: 0, writer }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write(&mut self, bytes: impl AsRef<[u8]>) -> Result<()> {
|
||||||
|
self.writer.write_all(bytes.as_ref()).map_err(Error::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add_indent(&mut self) -> Result<()> {
|
||||||
|
for _ in 0..self.level.saturating_sub(1) {
|
||||||
|
self.write(INDENT)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn ensure_top_level_struct(&self) -> Result<()> {
|
fn ensure_top_level_struct(&self) -> Result<()> {
|
||||||
if self.level == 0 {
|
if self.level == 0 {
|
||||||
return Err(Error::new(ErrorCode::ExpectedTopLevelObject, 0, 0, None));
|
return Err(Error::new(ErrorCode::ExpectedTopLevelObject, 0, 0, None));
|
||||||
|
@ -40,7 +79,10 @@ impl Serializer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> serde::ser::Serializer for &'a mut Serializer {
|
impl<'a, W> serde::ser::Serializer for &'a mut Serializer<W>
|
||||||
|
where
|
||||||
|
W: io::Write,
|
||||||
|
{
|
||||||
type Ok = ();
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
@ -54,7 +96,7 @@ impl<'a> serde::ser::Serializer for &'a mut Serializer {
|
||||||
|
|
||||||
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
|
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
|
||||||
self.ensure_top_level_struct()?;
|
self.ensure_top_level_struct()?;
|
||||||
self.output += if v { "true" } else { "false" };
|
self.write(if v { "true" } else { "false" })?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,8 +114,7 @@ impl<'a> serde::ser::Serializer for &'a mut Serializer {
|
||||||
|
|
||||||
fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
|
fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
|
||||||
self.ensure_top_level_struct()?;
|
self.ensure_top_level_struct()?;
|
||||||
self.output += &v.to_string();
|
self.serialize_str(&format!("{}", v))
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
|
fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
|
||||||
|
@ -90,33 +131,25 @@ impl<'a> serde::ser::Serializer for &'a mut Serializer {
|
||||||
|
|
||||||
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
|
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
|
||||||
self.ensure_top_level_struct()?;
|
self.ensure_top_level_struct()?;
|
||||||
self.output += &v.to_string();
|
self.serialize_str(&format!("{}", v))
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
|
fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
|
||||||
if v.is_finite() {
|
self.serialize_f64(v.into())
|
||||||
self.serialize_f64(v.into())
|
|
||||||
} else {
|
|
||||||
self.ensure_top_level_struct()?;
|
|
||||||
self.output += "null";
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
|
fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
|
||||||
self.ensure_top_level_struct()?;
|
self.ensure_top_level_struct()?;
|
||||||
if v.is_finite() {
|
if !v.is_finite() {
|
||||||
self.output += &v.to_string();
|
return Err(Error::new(ErrorCode::NonFiniteFloat, 0, 0, None));
|
||||||
} else {
|
|
||||||
self.output += "null";
|
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
|
self.serialize_str(&format!("{}", v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_char(self, v: char) -> Result<Self::Ok> {
|
fn serialize_char(self, v: char) -> Result<Self::Ok> {
|
||||||
let mut buf = [0; 4];
|
let mut buf = [0; 4];
|
||||||
self.serialize_str(v.encode_utf8(&mut buf))
|
self.serialize_bytes(v.encode_utf8(&mut buf).as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
|
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
|
||||||
|
@ -126,45 +159,52 @@ impl<'a> serde::ser::Serializer for &'a mut Serializer {
|
||||||
v.is_empty() || v.contains([' ', '\n', '\r', '\t', '=', '\'', '"', '\\', ':']);
|
v.is_empty() || v.contains([' ', '\n', '\r', '\t', '=', '\'', '"', '\\', ':']);
|
||||||
|
|
||||||
if needs_quotes {
|
if needs_quotes {
|
||||||
self.output += "\"";
|
self.write(b"\"")?;
|
||||||
|
|
||||||
|
// Since we've added a layer of quotes, we now need to escape
|
||||||
|
// certain characters.
|
||||||
for c in v.chars() {
|
for c in v.chars() {
|
||||||
match c {
|
match c {
|
||||||
'\t' => {
|
'\t' => {
|
||||||
self.output.push('\\');
|
self.write(b"\\")?;
|
||||||
self.output.push('t');
|
self.write(b"t")?;
|
||||||
}
|
}
|
||||||
'\n' => {
|
'\n' => {
|
||||||
self.output.push('\\');
|
self.write(b"\\")?;
|
||||||
self.output.push('n');
|
self.write(b"n")?;
|
||||||
}
|
}
|
||||||
'\r' => {
|
'\r' => {
|
||||||
self.output.push('\\');
|
self.write(b"\\")?;
|
||||||
self.output.push('r');
|
self.write(b"r")?;
|
||||||
}
|
}
|
||||||
'"' => {
|
'"' => {
|
||||||
self.output.push('\\');
|
self.write(b"\\")?;
|
||||||
self.output.push('"');
|
self.write(b"\"")?;
|
||||||
}
|
}
|
||||||
'\\' => {
|
'\\' => {
|
||||||
self.output.push('\\');
|
self.write(b"\\")?;
|
||||||
self.output.push('\\');
|
self.write(b"\\")?;
|
||||||
}
|
}
|
||||||
c => {
|
c => {
|
||||||
self.output.push(c);
|
self.serialize_char(c)?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
self.output += "\"";
|
self.write(b"\"")?;
|
||||||
} else {
|
} else {
|
||||||
self.output += v;
|
self.write(v.as_bytes())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok> {
|
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
|
||||||
todo!()
|
self.ensure_top_level_struct()?;
|
||||||
|
// For now we assume that the byte array contains
|
||||||
|
// valid SJSON.
|
||||||
|
// TODO: Turn this into an actual array of encoded bytes.
|
||||||
|
self.write(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_none(self) -> Result<Self::Ok> {
|
fn serialize_none(self) -> Result<Self::Ok> {
|
||||||
|
@ -184,8 +224,7 @@ impl<'a> serde::ser::Serializer for &'a mut Serializer {
|
||||||
|
|
||||||
fn serialize_unit(self) -> Result<Self::Ok> {
|
fn serialize_unit(self) -> Result<Self::Ok> {
|
||||||
self.ensure_top_level_struct()?;
|
self.ensure_top_level_struct()?;
|
||||||
self.output += "null";
|
self.write(b"null")
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
|
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
|
||||||
|
@ -223,19 +262,18 @@ impl<'a> serde::ser::Serializer for &'a mut Serializer {
|
||||||
{
|
{
|
||||||
self.ensure_top_level_struct()?;
|
self.ensure_top_level_struct()?;
|
||||||
|
|
||||||
self.output += "{ ";
|
self.write(b"{ ")?;
|
||||||
variant.serialize(&mut *self)?;
|
variant.serialize(&mut *self)?;
|
||||||
self.output += " = ";
|
self.write(b" = ")?;
|
||||||
value.serialize(&mut *self)?;
|
value.serialize(&mut *self)?;
|
||||||
self.output += " }\n";
|
self.write(b" }")
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize the start of a sequence.
|
// Serialize the start of a sequence.
|
||||||
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
|
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
|
||||||
self.ensure_top_level_struct()?;
|
self.ensure_top_level_struct()?;
|
||||||
|
|
||||||
self.output += "[\n";
|
self.write(b"[\n")?;
|
||||||
self.level += 1;
|
self.level += 1;
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
@ -266,7 +304,7 @@ impl<'a> serde::ser::Serializer for &'a mut Serializer {
|
||||||
|
|
||||||
variant.serialize(&mut *self)?;
|
variant.serialize(&mut *self)?;
|
||||||
|
|
||||||
self.output += " = [\n";
|
self.write(b" = [\n")?;
|
||||||
self.level += 1;
|
self.level += 1;
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
|
@ -274,7 +312,7 @@ impl<'a> serde::ser::Serializer for &'a mut Serializer {
|
||||||
|
|
||||||
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
|
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
|
||||||
if self.level > 0 {
|
if self.level > 0 {
|
||||||
self.output += "{\n";
|
self.write(b"{\n")?;
|
||||||
}
|
}
|
||||||
self.level += 1;
|
self.level += 1;
|
||||||
Ok(self)
|
Ok(self)
|
||||||
|
@ -296,7 +334,7 @@ impl<'a> serde::ser::Serializer for &'a mut Serializer {
|
||||||
|
|
||||||
variant.serialize(&mut *self)?;
|
variant.serialize(&mut *self)?;
|
||||||
|
|
||||||
self.output += " = {\n";
|
self.write(b" = {\n")?;
|
||||||
self.level += 1;
|
self.level += 1;
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
|
@ -310,7 +348,10 @@ impl<'a> serde::ser::Serializer for &'a mut Serializer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> serde::ser::SerializeSeq for &'a mut Serializer {
|
impl<'a, W> serde::ser::SerializeSeq for &'a mut Serializer<W>
|
||||||
|
where
|
||||||
|
W: io::Write,
|
||||||
|
{
|
||||||
type Ok = ();
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
@ -318,23 +359,22 @@ impl<'a> serde::ser::SerializeSeq for &'a mut Serializer {
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
value.serialize(&mut **self)?;
|
value.serialize(&mut **self)?;
|
||||||
if !self.output.ends_with('\n') {
|
self.write(b"\n")
|
||||||
self.output += "\n";
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
self.output += "]\n";
|
self.write(b"]")
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> serde::ser::SerializeTuple for &'a mut Serializer {
|
impl<'a, W> serde::ser::SerializeTuple for &'a mut Serializer<W>
|
||||||
|
where
|
||||||
|
W: io::Write,
|
||||||
|
{
|
||||||
type Ok = ();
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
@ -342,23 +382,22 @@ impl<'a> serde::ser::SerializeTuple for &'a mut Serializer {
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
value.serialize(&mut **self)?;
|
value.serialize(&mut **self)?;
|
||||||
if !self.output.ends_with('\n') {
|
self.write(b"\n")
|
||||||
self.output += "\n";
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
self.output += "]\n";
|
self.write(b"]")
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> serde::ser::SerializeTupleStruct for &'a mut Serializer {
|
impl<'a, W> serde::ser::SerializeTupleStruct for &'a mut Serializer<W>
|
||||||
|
where
|
||||||
|
W: io::Write,
|
||||||
|
{
|
||||||
type Ok = ();
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
@ -366,23 +405,22 @@ impl<'a> serde::ser::SerializeTupleStruct for &'a mut Serializer {
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
value.serialize(&mut **self)?;
|
value.serialize(&mut **self)?;
|
||||||
if !self.output.ends_with('\n') {
|
self.write(b"\n")
|
||||||
self.output += "\n";
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
self.output += "]\n";
|
self.write(b"]")
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> serde::ser::SerializeTupleVariant for &'a mut Serializer {
|
impl<'a, W> serde::ser::SerializeTupleVariant for &'a mut Serializer<W>
|
||||||
|
where
|
||||||
|
W: io::Write,
|
||||||
|
{
|
||||||
type Ok = ();
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
@ -390,28 +428,31 @@ impl<'a> serde::ser::SerializeTupleVariant for &'a mut Serializer {
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
value.serialize(&mut **self)?;
|
value.serialize(&mut **self)?;
|
||||||
if !self.output.ends_with('\n') {
|
self.write(b"\n")
|
||||||
self.output += "\n";
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
self.output += "]\n";
|
self.write(b"]\n")?;
|
||||||
|
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
|
|
||||||
if self.level > 0 {
|
if self.level > 0 {
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
self.output += "}\n";
|
self.write(b"}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> serde::ser::SerializeMap for &'a mut Serializer {
|
impl<'a, W> serde::ser::SerializeMap for &'a mut Serializer<W>
|
||||||
|
where
|
||||||
|
W: io::Write,
|
||||||
|
{
|
||||||
type Ok = ();
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
@ -419,7 +460,7 @@ impl<'a> serde::ser::SerializeMap for &'a mut Serializer {
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
key.serialize(&mut **self)
|
key.serialize(&mut **self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,25 +471,25 @@ impl<'a> serde::ser::SerializeMap for &'a mut Serializer {
|
||||||
// It doesn't make a difference where the `=` is added. But doing it here
|
// It doesn't make a difference where the `=` is added. But doing it here
|
||||||
// means `serialize_key` is only a call to a different function, which should
|
// means `serialize_key` is only a call to a different function, which should
|
||||||
// have greater optimization potential for the compiler.
|
// have greater optimization potential for the compiler.
|
||||||
self.output += " = ";
|
self.write(b" = ")?;
|
||||||
value.serialize(&mut **self)?;
|
value.serialize(&mut **self)?;
|
||||||
if !self.output.ends_with('\n') {
|
self.write(b"\n")
|
||||||
self.output += "\n";
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
if self.level > 1 {
|
if self.level > 1 {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
self.output += "}\n";
|
self.write(b"}")?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> serde::ser::SerializeStruct for &'a mut Serializer {
|
impl<'a, W> serde::ser::SerializeStruct for &'a mut Serializer<W>
|
||||||
|
where
|
||||||
|
W: io::Write,
|
||||||
|
{
|
||||||
type Ok = ();
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
@ -456,29 +497,29 @@ impl<'a> serde::ser::SerializeStruct for &'a mut Serializer {
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
key.serialize(&mut **self)?;
|
key.serialize(&mut **self)?;
|
||||||
|
|
||||||
self.output += " = ";
|
self.write(b" = ")?;
|
||||||
|
|
||||||
value.serialize(&mut **self)?;
|
value.serialize(&mut **self)?;
|
||||||
if !self.output.ends_with('\n') {
|
self.write(b"\n")
|
||||||
self.output += "\n";
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
if self.level > 1 {
|
if self.level > 1 {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
self.output += "}\n";
|
self.write(b"}")?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> serde::ser::SerializeStructVariant for &'a mut Serializer {
|
impl<'a, W> serde::ser::SerializeStructVariant for &'a mut Serializer<W>
|
||||||
|
where
|
||||||
|
W: std::io::Write,
|
||||||
|
{
|
||||||
type Ok = ();
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
@ -486,21 +527,18 @@ impl<'a> serde::ser::SerializeStructVariant for &'a mut Serializer {
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
key.serialize(&mut **self)?;
|
key.serialize(&mut **self)?;
|
||||||
self.output += " = ";
|
self.write(b" = ")?;
|
||||||
value.serialize(&mut **self)?;
|
value.serialize(&mut **self)?;
|
||||||
if !self.output.ends_with('\n') {
|
self.write(b"\n")
|
||||||
self.output += "\n";
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok> {
|
fn end(self) -> Result<Self::Ok> {
|
||||||
if self.level > 0 {
|
if self.level > 0 {
|
||||||
self.level -= 1;
|
self.level -= 1;
|
||||||
self.add_indent();
|
self.add_indent()?;
|
||||||
self.output += "}\n";
|
self.write(b"}")?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use serde_sjson::to_string;
|
use serde_sjson::{to_string, Error};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize_null() {
|
fn serialize_null() {
|
||||||
|
@ -81,17 +81,14 @@ fn serialize_non_representable_floats() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let tests = [std::f64::NAN, std::f64::INFINITY, std::f64::NEG_INFINITY];
|
let tests = [std::f64::NAN, std::f64::INFINITY, std::f64::NEG_INFINITY];
|
||||||
let expected = String::from("value = null\n");
|
|
||||||
for value in tests {
|
for value in tests {
|
||||||
let value = Value64 { value };
|
let value = Value64 { value };
|
||||||
let actual = to_string(&value).unwrap();
|
assert!(to_string(&value).is_err());
|
||||||
assert_eq!(actual, expected);
|
|
||||||
}
|
}
|
||||||
let tests = [std::f32::NAN, std::f32::INFINITY, std::f32::NEG_INFINITY];
|
let tests = [std::f32::NAN, std::f32::INFINITY, std::f32::NEG_INFINITY];
|
||||||
for value in tests {
|
for value in tests {
|
||||||
let value = Value32 { value };
|
let value = Value32 { value };
|
||||||
let actual = to_string(&value).unwrap();
|
assert!(to_string(&value).is_err());
|
||||||
assert_eq!(actual, expected);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue