//! Serialize a Rust data structure into JSON data.
usecrate::error::{Error, ErrorCode, Result}; usecrate::io; use alloc::string::{String, ToString}; use alloc::vec::Vec; use core::fmt::{self, Display}; use core::num::FpCategory; use serde::ser::{self, Impossible, Serialize};
/// A structure for serializing Rust values into JSON. #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pubstruct Serializer<W, F = CompactFormatter> {
writer: W,
formatter: F,
}
impl<W> Serializer<W> where
W: io::Write,
{ /// Creates a new JSON serializer. #[inline] pubfn new(writer: W) -> Self {
Serializer::with_formatter(writer, CompactFormatter)
}
}
impl<'a, W> Serializer<W, PrettyFormatter<'a>> where
W: io::Write,
{ /// Creates a new JSON pretty print serializer. #[inline] pubfn pretty(writer: W) -> Self {
Serializer::with_formatter(writer, PrettyFormatter::new())
}
}
impl<W, F> Serializer<W, F> where
W: io::Write,
F: Formatter,
{ /// Creates a new JSON visitor whose output will be written to the writer /// specified. #[inline] pubfn with_formatter(writer: W, formatter: F) -> Self {
Serializer { writer, formatter }
}
/// Unwrap the `Writer` from the `Serializer`. #[inline] pubfn into_inner(self) -> W { self.writer
}
}
impl<'a, W, F> ser::Serializer for &'a mut Serializer<W, F> where
W: io::Write,
F: Formatter,
{ type Ok = (); type Error = Error;
type SerializeSeq = Compound<'a, W, F>; type SerializeTuple = Compound<'a, W, F>; type SerializeTupleStruct = Compound<'a, W, F>; type SerializeTupleVariant = Compound<'a, W, F>; type SerializeMap = Compound<'a, W, F>; type SerializeStruct = Compound<'a, W, F>; type SerializeStructVariant = Compound<'a, W, F>;
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>;
#[cfg(feature = "arbitrary_precision")] struct NumberStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer<W, F>);
#[cfg(feature = "arbitrary_precision")] impl<'a, W: io::Write, F: Formatter> ser::Serializer for NumberStrEmitter<'a, W, F> { 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>;
#[cfg(feature = "raw_value")] struct RawValueStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer<W, F>);
#[cfg(feature = "raw_value")] impl<'a, W: io::Write, F: Formatter> ser::Serializer for RawValueStrEmitter<'a, W, F> { 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>;
/// Represents a character escape code in a type-safe manner. pubenum CharEscape { /// An escaped quote `"`
Quote, /// An escaped reverse solidus `\`
ReverseSolidus, /// An escaped solidus `/`
Solidus, /// An escaped backspace character (usually escaped as `\b`)
Backspace, /// An escaped form feed character (usually escaped as `\f`)
FormFeed, /// An escaped line feed character (usually escaped as `\n`)
LineFeed, /// An escaped carriage return character (usually escaped as `\r`)
CarriageReturn, /// An escaped tab character (usually escaped as `\t`)
Tab, /// An escaped ASCII plane control character (usually escaped as /// `\u00XX` where `XX` are two hex characters)
AsciiControl(u8),
}
/// This trait abstracts away serializing the JSON control characters, which allows the user to /// optionally pretty print the JSON output. pubtrait Formatter { /// Writes a `null` value to the specified writer. #[inline] fn write_null<W>(&mutself, writer: &mut W) -> io::Result<()> where
W: ?Sized + io::Write,
{
writer.write_all(b"null")
}
/// Writes a `true` or `false` value to the specified writer. #[inline] fn write_bool<W>(&mutself, writer: &mut W, value: bool) -> io::Result<()> where
W: ?Sized + io::Write,
{ let s = if value {
b"true"as &[u8]
} else {
b"false"as &[u8]
};
writer.write_all(s)
}
/// Writes an integer value like `-123` to the specified writer. #[inline] fn write_i8<W>(&mutself, writer: &mut W, value: i8) -> io::Result<()> where
W: ?Sized + io::Write,
{ letmut buffer = itoa::Buffer::new(); let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
/// Writes an integer value like `-123` to the specified writer. #[inline] fn write_i16<W>(&mutself, writer: &mut W, value: i16) -> io::Result<()> where
W: ?Sized + io::Write,
{ letmut buffer = itoa::Buffer::new(); let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
/// Writes an integer value like `-123` to the specified writer. #[inline] fn write_i32<W>(&mutself, writer: &mut W, value: i32) -> io::Result<()> where
W: ?Sized + io::Write,
{ letmut buffer = itoa::Buffer::new(); let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
/// Writes an integer value like `-123` to the specified writer. #[inline] fn write_i64<W>(&mutself, writer: &mut W, value: i64) -> io::Result<()> where
W: ?Sized + io::Write,
{ letmut buffer = itoa::Buffer::new(); let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
/// Writes an integer value like `-123` to the specified writer. #[inline] fn write_i128<W>(&mutself, writer: &mut W, value: i128) -> io::Result<()> where
W: ?Sized + io::Write,
{ letmut buffer = itoa::Buffer::new(); let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
/// Writes an integer value like `123` to the specified writer. #[inline] fn write_u8<W>(&mutself, writer: &mut W, value: u8) -> io::Result<()> where
W: ?Sized + io::Write,
{ letmut buffer = itoa::Buffer::new(); let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
/// Writes an integer value like `123` to the specified writer. #[inline] fn write_u16<W>(&mutself, writer: &mut W, value: u16) -> io::Result<()> where
W: ?Sized + io::Write,
{ letmut buffer = itoa::Buffer::new(); let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
/// Writes an integer value like `123` to the specified writer. #[inline] fn write_u32<W>(&mutself, writer: &mut W, value: u32) -> io::Result<()> where
W: ?Sized + io::Write,
{ letmut buffer = itoa::Buffer::new(); let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
/// Writes an integer value like `123` to the specified writer. #[inline] fn write_u64<W>(&mutself, writer: &mut W, value: u64) -> io::Result<()> where
W: ?Sized + io::Write,
{ letmut buffer = itoa::Buffer::new(); let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
/// Writes an integer value like `123` to the specified writer. #[inline] fn write_u128<W>(&mutself, writer: &mut W, value: u128) -> io::Result<()> where
W: ?Sized + io::Write,
{ letmut buffer = itoa::Buffer::new(); let s = buffer.format(value);
writer.write_all(s.as_bytes())
}
/// Writes a floating point value like `-31.26e+12` to the specified writer. #[inline] fn write_f32<W>(&mutself, writer: &mut W, value: f32) -> io::Result<()> where
W: ?Sized + io::Write,
{ letmut buffer = ryu::Buffer::new(); let s = buffer.format_finite(value);
writer.write_all(s.as_bytes())
}
/// Writes a floating point value like `-31.26e+12` to the specified writer. #[inline] fn write_f64<W>(&mutself, writer: &mut W, value: f64) -> io::Result<()> where
W: ?Sized + io::Write,
{ letmut buffer = ryu::Buffer::new(); let s = buffer.format_finite(value);
writer.write_all(s.as_bytes())
}
/// Writes a number that has already been rendered to a string. #[inline] fn write_number_str<W>(&mutself, writer: &>mut W, value: &str) -> io::Result<()> where
W: ?Sized + io::Write,
{
writer.write_all(value.as_bytes())
}
/// Called before each series of `write_string_fragment` and /// `write_char_escape`. Writes a `"` to the specified writer. #[inline] fn begin_string<W>(&mutself, writer: &mutW) -> io::Result<()> where
W: ?Sized + io::Write,
{
writer.write_all(b"\"")
}
/// Called after each series of `write_string_fragment` and /// `write_char_escape`. Writes a `"` to the specified writer. #[inline] fn end_string<W>(&mutself, writer: &mut W) -> io::Result<()> where
W: ?Sized + io::Write,
{
writer.write_all(b"\"")
}
/// Writes a string fragment that doesn't need any escaping to the /// specified writer. #[inline] fn write_string_fragment<W>(&mutself, writer: &mut W, fragment: &str) -> io::Result<()> where
W: ?Sized + io::Write,
{
writer.write_all(fragment.as_bytes())
}
/// Writes a character escape code to the specified writer. #[inline] fn write_char_escape<W>(&mutself, writer: &mut W, char_escape: CharEscape) -> io::Result<()> where
W: ?Sized + io::Write,
{ useself::CharEscape::*;
/// Writes the representation of a byte array. Formatters can choose whether /// to represent bytes as a JSON array of integers (the default), or some /// JSON string encoding like hex or base64. fn write_byte_array<W>(&mutself, writer: &>mut W, value: &[u8]) -> io::Result<()> where
W: ?Sized + io::Write,
{
tri!(self.begin_array(writer)); letmut first = true; for byte in value {
tri!(self.begin_array_value(writer, first));
tri!(self.write_u8(writer, *byte));
tri!(self.end_array_value(writer));
first = false;
} self.end_array(writer)
}
/// Called before every array. Writes a `[` to the specified /// writer. #[inline] fn begin_array<W>(&mutself, writer: &mut W) -> io::Result<()> where
W: ?Sized + io::Write,
{
writer.write_all(b"[")
}
/// Called after every array. Writes a `]` to the specified /// writer. #[inline] fn end_array<W>(&mutself, writer: &mut W) -> io::Result<()> where
W: ?Sized + io::Write,
{
writer.write_all(b"]")
}
/// Called before every array value. Writes a `,` if needed to /// the specified writer. #[inline] fn begin_array_value<W>(&mutself, writer: &mut W, first: bool) -> io::Result<()> where
W: ?Sized + io::Write,
{ if first {
Ok(())
} else {
writer.write_all(b",")
}
}
/// Called after every array value. #[inline] fn end_array_value<W>(&mutself, _writer: &>mut W) -> io::Result<()> where
W: ?Sized + io::Write,
{
Ok(())
}
/// Called before every object. Writes a `{` to the specified /// writer. #[inline] fn begin_object<W>(&mutself, writer: &mutW) -> io::Result<()> where
W: ?Sized + io::Write,
{
writer.write_all(b"{")
}
/// Called after every object. Writes a `}` to the specified /// writer. #[inline] fn end_object<W>(&mutself, writer: &mut W) -> io::Result<()> where
W: ?Sized + io::Write,
{
writer.write_all(b"}")
}
/// Called before every object key. #[inline] fn begin_object_key<W>(&mutself, writer: &>mut W, first: bool) -> io::Result<()> where
W: ?Sized + io::Write,
{ if first {
Ok(())
} else {
writer.write_all(b",")
}
}
/// Called after every object key. A `:` should be written to the /// specified writer by either this method or /// `begin_object_value`. #[inline] fn end_object_key<W>(&mutself, _writer: &mut W) -> io::Result<()> where
W: ?Sized + io::Write,
{
Ok(())
}
/// Called before every object value. A `:` should be written to /// the specified writer by either this method or /// `end_object_key`. #[inline] fn begin_object_value<W>(&mutself, writer: &mut W) -> io::Result<()> where
W: ?Sized + io::Write,
{
writer.write_all(b":")
}
/// Called after every object value. #[inline] fn end_object_value<W>(&mutself, _writer: &mut W) -> io::Result<()> where
W: ?Sized + io::Write,
{
Ok(())
}
/// Writes a raw JSON fragment that doesn't need any escaping to the /// specified writer. #[inline] fn write_raw_fragment<W>(&mutself, writer: &mut W, fragment: &str) -> io::Result<()> where
W: ?Sized + io::Write,
{
writer.write_all(fragment.as_bytes())
}
}
/// This structure compacts a JSON value with no extra whitespace. #[derive(Clone, Debug)] pubstruct CompactFormatter;
impl Formatter for CompactFormatter {}
/// This structure pretty prints a JSON value to make it human readable. #[derive(Clone, Debug)] pubstruct PrettyFormatter<'a> {
current_indent: usize,
has_value: bool,
indent: &'a [u8],
}
impl<'a> PrettyFormatter<'a> { /// Construct a pretty printer formatter that defaults to using two spaces for indentation. pubfn new() -> Self {
PrettyFormatter::with_indent(b" ")
}
/// Construct a pretty printer formatter that uses the `indent` string for indentation. pubfn with_indent(indent: &'a [u8]) -> Self {
PrettyFormatter {
current_indent: 0,
has_value: false,
indent,
}
}
}
/// Serialize the given data structure as JSON into the I/O stream. /// /// Serialization guarantees it only feeds valid UTF-8 sequences to the writer. /// /// # Errors /// /// Serialization can fail if `T`'s implementation of `Serialize` decides to /// fail, or if `T` contains a map with non-string keys. #[inline] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pubfn to_writer<W, T>(writer: W, value: &T) -> Result<()> where
W: io::Write,
T: ?Sized + Serialize,
{ letmut ser = Serializer::new(writer);
value.serialize(&mut ser)
}
/// Serialize the given data structure as pretty-printed JSON into the I/O /// stream. /// /// Serialization guarantees it only feeds valid UTF-8 sequences to the writer. /// /// # Errors /// /// Serialization can fail if `T`'s implementation of `Serialize` decides to /// fail, or if `T` contains a map with non-string keys. #[inline] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pubfn to_writer_pretty<W, T>(writer: W, value: &T) -> Result<()> where
W: io::Write,
T: ?Sized + Serialize,
{ letmut ser = Serializer::pretty(writer);
value.serialize(&mut ser)
}
/// Serialize the given data structure as a JSON byte vector. /// /// # Errors /// /// Serialization can fail if `T`'s implementation of `Serialize` decides to /// fail, or if `T` contains a map with non-string keys. #[inline] pubfn to_vec<T>(value: &T) -> Result<Vec<u8>> where
T: ?Sized + Serialize,
{ letmut writer = Vec::with_capacity(128);
tri!(to_writer(&mut writer, value));
Ok(writer)
}
/// Serialize the given data structure as a pretty-printed JSON byte vector. /// /// # Errors /// /// Serialization can fail if `T`'s implementation of `Serialize` decides to /// fail, or if `T` contains a map with non-string keys. #[inline] pubfn to_vec_pretty<T>(value: &T) -> Result<Vec<u8>> where
T: ?Sized + Serialize,
{ letmut writer = Vec::with_capacity(128);
tri!(to_writer_pretty(&mut writer, value));
Ok(writer)
}
/// Serialize the given data structure as a String of JSON. /// /// # Errors /// /// Serialization can fail if `T`'s implementation of `Serialize` decides to /// fail, or if `T` contains a map with non-string keys. #[inline] pubfn to_string<T>(value: &T) -> Result<String> where
T: ?Sized + Serialize,
{ let vec = tri!(to_vec(value)); let string = unsafe { // We do not emit invalid UTF-8.
String::from_utf8_unchecked(vec)
};
Ok(string)
}
/// Serialize the given data structure as a pretty-printed String of JSON. /// /// # Errors /// /// Serialization can fail if `T`'s implementation of `Serialize` decides to /// fail, or if `T` contains a map with non-string keys. #[inline] pubfn to_string_pretty<T>(value: &T) -> Result<String> where
T: ?Sized + Serialize,
{ let vec = tri!(to_vec_pretty(value)); let string = unsafe { // We do not emit invalid UTF-8.
String::from_utf8_unchecked(vec)
};
Ok(string)
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.