//! Serialize a Rust data structure into MessagePack data.
usecrate::bytes::OnlyBytes; usecrate::config::BytesMode; use std::error; use std::fmt::{self, Display}; use std::io::Write; use std::marker::PhantomData;
use serde; use serde::ser::{
SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
SerializeTupleStruct, SerializeTupleVariant,
}; use serde::Serialize;
use rmp::encode::ValueWriteError; use rmp::{encode, Marker};
/// This type represents all possible errors that can occur when serializing or /// deserializing MessagePack data. #[derive(Debug)] pubenum Error { /// Failed to write a MessagePack value.
InvalidValueWrite(ValueWriteError), //TODO: This can be removed at some point /// Failed to serialize struct, sequence or map, because its length is unknown.
UnknownLength, /// Invalid Data model, i.e. Serialize trait is not implmented correctly
InvalidDataModel(&'static str), /// Depth limit exceeded
DepthLimitExceeded, /// Catchall for syntax error messages.
Syntax(String),
}
impl serde::ser::Error for Error { /// Raised when there is general error when deserializing a type. #[cold] fn custom<T: Display>(msg: T) -> Error {
Error::Syntax(msg.to_string())
}
}
/// Obtain the underlying writer. pubtrait UnderlyingWrite { /// Underlying writer type. type Write: Write;
/// Gets a reference to the underlying writer. fn get_ref(&self) -> &Self::Write;
/// Gets a mutable reference to the underlying writer. /// /// It is inadvisable to directly write to the underlying writer. fn get_mut(&mutself) -> &mutSelf::Write;
/// Unwraps this `Serializer`, returning the underlying writer. fn into_inner(self) -> Self::Write;
}
/// Represents MessagePack serialization implementation. /// /// # Note /// /// MessagePack has no specification about how to encode enum types. Thus we are free to do /// whatever we want, so the given choice may be not ideal for you. /// /// An enum value is represented as a single-entry map whose key is the variant /// id and whose value is a sequence containing all associated data. If the enum /// does not have associated data, the sequence is empty. /// /// All instances of `ErrorKind::Interrupted` are handled by this function and the underlying /// operation is retried. // TODO: Docs. Examples. #[derive(Debug)] pubstruct Serializer<W, C = DefaultConfig> {
wr: W,
depth: u16,
config: RuntimeConfig,
_back_compat_config: PhantomData<C>,
}
impl<W: Write, C> Serializer<W, C> { /// Gets a reference to the underlying writer. #[inline(always)] pubfn get_ref(&self) -> &W {
&self.wr
}
/// Gets a mutable reference to the underlying writer. /// /// It is inadvisable to directly write to the underlying writer. #[inline(always)] pubfn get_mut(&mutself) -> &mut W {
&mutself.wr
}
/// Unwraps this `Serializer`, returning the underlying writer. #[inline(always)] pubfn into_inner(self) -> W { self.wr
}
/// Changes the maximum nesting depth that is allowed. /// /// Currently unused. #[doc(hidden)] #[inline] pubfn unstable_set_max_depth(&mutself, depth: usize) { self.depth = depth.min(u16::MAX as _) as u16;
}
}
impl<W: Write> Serializer<W, DefaultConfig> { /// Constructs a new `MessagePack` serializer whose output will be written to the writer /// specified. /// /// # Note /// /// This is the default constructor, which returns a serializer that will serialize structs /// and enums using the most compact representation. #[inline] pubfn new(wr: W) -> Self {
Serializer {
wr,
depth: 1024,
config: RuntimeConfig::new(DefaultConfig),
_back_compat_config: PhantomData,
}
}
}
impl<W: Write, C> Serializer<W, C> { /// Consumes this serializer returning the new one, which will serialize structs as a map. /// /// This is used, when the default struct serialization as a tuple does not fit your /// requirements. #[inline] pubfn with_struct_map(self) -> Serializer<W, StructMapConfig<C>> { let Serializer { wr, depth, config, _back_compat_config: _ } = self;
Serializer {
wr,
depth,
config: RuntimeConfig::new(StructMapConfig::new(config)),
_back_compat_config: PhantomData,
}
}
/// Consumes this serializer returning the new one, which will serialize structs as a tuple /// without field names. /// /// This is the default MessagePack serialization mechanism, emitting the most compact /// representation. #[inline] pubfn with_struct_tuple(self) -> Serializer<W, StructTupleConfig<C>> { let Serializer { wr, depth, config, _back_compat_config: _ } = self;
Serializer {
wr,
depth,
config: RuntimeConfig::new(StructTupleConfig::new(config)),
_back_compat_config: PhantomData,
}
}
/// Consumes this serializer returning the new one, which will serialize some types in /// human-readable representations (`Serializer::is_human_readable` will return `true`). Note /// that the overall representation is still binary, but some types such as IP addresses will /// be saved as human-readable strings. /// /// This is primarily useful if you need to interoperate with serializations produced by older /// versions of `rmp-serde`. #[inline] pubfn with_human_readable(self) -> Serializer<W, HumanReadableConfig<C>> { let Serializer { wr, depth, config, _back_compat_config: _ } = self;
Serializer {
wr,
depth,
config: RuntimeConfig::new(HumanReadableConfig::new(config)),
_back_compat_config: PhantomData,
}
}
/// Consumes this serializer returning the new one, which will serialize types as binary /// (`Serializer::is_human_readable` will return `false`). /// /// This is the default MessagePack serialization mechanism, emitting the most compact /// representation. #[inline] pubfn with_binary(self) -> Serializer<W, BinaryConfig<C>> { let Serializer { wr, depth, config, _back_compat_config: _ } = self;
Serializer {
wr,
depth,
config: RuntimeConfig::new(BinaryConfig::new(config)),
_back_compat_config: PhantomData,
}
}
/// Prefer encoding sequences of `u8` as bytes, rather than /// as a sequence of variable-size integers. /// /// This reduces overhead of binary data, but it may break /// decodnig of some Serde types that happen to contain `[u8]`s, /// but don't implement Serde's `visit_bytes`. /// /// ```rust /// use serde::ser::Serialize; /// let mut msgpack_data = Vec::new(); /// let mut serializer = rmp_serde::Serializer::new(&mut msgpack_data) /// .with_bytes(rmp_serde::config::BytesMode::ForceAll); /// vec![255u8; 100].serialize(&mut serializer).unwrap(); /// ``` #[inline] pubfn with_bytes(mutself, mode: BytesMode) -> Serializer<W, C> { self.config.bytes = mode; self
}
}
impl<W: Write, C> UnderlyingWrite for Serializer<W, C> { type Write = W;
/// Hack to store fixed-size arrays (which serde says are tuples) #[derive(Debug)] #[doc(hidden)] pubstruct Tuple<'a, W, C> {
len: u32, // can't know if all elements are u8 until the end ;(
buf: Option<Vec<u8>>,
se: &'a mut Serializer<W, C>,
}
impl<'a, W: Write + 'a, C: SerializerConfig> SerializeTuple for Tuple<'a, W, C> { type Ok = (); type Error = Error;
/// Contains a `Serializer` for sequences and maps whose length is not yet known /// and a counter for the number of elements that are encoded by the `Serializer`. #[derive(Debug)] struct UnknownLengthCompound {
se: Serializer<Vec<u8>, DefaultConfig>,
elem_count: u32,
}
/// Contains a `Serializer` for encoding elements of sequences and maps. /// /// # Note /// /// If , for example, a field inside a struct is tagged with `#serde(flatten)` the total number of /// fields of this struct will be unknown to serde because flattened fields may have name clashes /// and then will be overwritten. So, serde wants to serialize the struct as a map with an unknown /// length. /// /// For the described case a `UnknownLengthCompound` is used to encode the elements. On `end()` /// the counted length and the encoded elements will be written to the `Serializer`. A caveat is, /// that structs that contain flattened fields arem always written as a map, even when compact /// representaion is desired. /// /// Otherwise, if the length is known, the elements will be encoded directly by the `Serializer`. #[derive(Debug)] #[doc(hidden)] pubstruct MaybeUnknownLengthCompound<'a, W, C> {
se: &'a mut Serializer<W, C>,
compound: Option<UnknownLengthCompound>,
}
impl<'a, W: Write + 'a, C: SerializerConfig> SerializeSeq for MaybeUnknownLengthCompound<'a, W, C> { type Ok = (); type Error = Error;
// Encode as if it's inner type.
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized + serde::Serialize>(self, _name: &'static str, _: u32, variant: &'static str, value: &T) -> Result<Self::Ok, Self::Error> { // encode as a map from variant idx to its attributed data, like: {idx => value}
encode::write_map_len(&mutself.wr, 1)?; self.serialize_str(variant)?;
value.serialize(self)
}
#[inline] fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> { self.maybe_unknown_len_compound(len.map(|len| len as u32), |wr, len| encode::write_array_len(wr, len))
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
Ok(Tuple {
buf: ifself.config.bytes == BytesMode::ForceAll && len > 0 {
Some(Vec::new())
} else {
encode::write_array_len(&mutself.wr, len as u32)?;
None
},
len: len as u32,
se: self,
})
}
fn serialize_tuple_struct(self, _name: &'static str, len: usize) ->
Result<Self::SerializeTupleStruct, Self::Error>
{
encode::write_array_len(&mutself.wr, len as u32)?;
self.compound()
}
fn serialize_tuple_variant(self, _name: &'static str, _: u32, variant: &'static str, len: usize) ->
Result<Self::SerializeTupleVariant, Error>
{ // encode as a map from variant idx to a sequence of its attributed data, like: {idx => [v1,...,vN]}
encode::write_map_len(&mutself.wr, 1)?; self.serialize_str(variant)?;
encode::write_array_len(&mutself.wr, len as u32)?; self.compound()
}
#[inline] fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Error> { self.maybe_unknown_len_compound(len.map(|len| len as u32), |wr, len| encode::write_map_len(wr, len))
}
fn serialize_struct(self, _name: &'static str, len: usize) ->
Result<Self::SerializeStruct, Self::Error>
{ ifself.config.is_named {
encode::write_map_len(self.get_mut(), len as u32)?;
} else {
encode::write_array_len(self.get_mut(), len as u32)?;
} self.compound()
}
fn serialize_struct_variant(self, name: &'static str, _: u32, variant: &'static str, len: usize) ->
Result<Self::SerializeStructVariant, Error>
{ // encode as a map from variant idx to a sequence of its attributed data, like: {idx => [v1,...,vN]}
encode::write_map_len(&mutself.wr, 1)?; self.serialize_str(variant)?; self.serialize_struct(name, len)
}
fn collect_seq<I>(self, iter: I) -> Result<Self::Ok, Self::Error> where I: IntoIterator, I::Item: Serialize { let iter = iter.into_iter(); let len = match iter.size_hint() {
(lo, Some(hi)) if lo == hi && lo <= u32::MAX as usize => Some(lo as u32),
_ => None,
};
// Estimate whether the input is `&[u8]` or similar (hacky, because Rust lacks proper specialization) let might_be_a_bytes_iter = (std::mem::size_of::<I::Item>() == 1 || std::mem::size_of::<I::Item>() == ITEM_PTR_SIZE) // Complex types like HashSet<u8> don't support reading bytes. // The simplest iterator is ptr+len.
&& std::mem::size_of::<I::IntoIter>() <= MAX_ITER_SIZE;
letmut iter = iter.peekable(); if might_be_a_bytes_iter && self.config.bytes != BytesMode::Normal { iflet Some(len) = len { // The `OnlyBytes` serializer emits `Err` for everything except `u8` if iter.peek().map_or(false, |item| item.serialize(OnlyBytes).is_ok()) { returnself.bytes_from_iter(iter, len);
}
}
}
letmut serializer = self.serialize_seq(len.map(|len| len as usize))?;
iter.try_for_each(|item| serializer.serialize_element(&item))?;
SerializeSeq::end(serializer)
}
}
impl<'a, W: Write + 'a> serde::Serializer for &mut ExtFieldSerializer<'a, W> { type Ok = (); type Error = Error;
type SerializeSeq = serde::ser::Impossible<(), Error>; type SerializeTuple = serde::ser::Impossible<(), Error>; type SerializeTupleStruct = serde::ser::Impossible<(), Error>; type SerializeTupleVariant = serde::ser::Impossible<(), Error>; type SerializeMap = serde::ser::Impossible<(), Error>; type SerializeStruct = serde::ser::Impossible<(), Error>; type SerializeStructVariant = serde::ser::Impossible<(), Error>;
impl<'a, W: Write + 'a> serde::ser::Serializer for &mut ExtSerializer<'a, W> { type Ok = (); type Error = Error;
type SerializeSeq = serde::ser::Impossible<(), Error>; type SerializeTuple = Self; type SerializeTupleStruct = serde::ser::Impossible<(), Error>; type SerializeTupleVariant = serde::ser::Impossible<(), Error>; type SerializeMap = serde::ser::Impossible<(), Error>; type SerializeStruct = serde::ser::Impossible<(), Error>; type SerializeStructVariant = serde::ser::Impossible<(), Error>;
/// Serialize the given data structure as MessagePack into the I/O stream. /// This function uses compact representation - structures as arrays /// /// Serialization can fail if `T`'s implementation of `Serialize` decides to fail. #[inline] pubfn write<W, T>(wr: &mut W, val: &T) -> Result<(), Error> where
W: Write + ?Sized,
T: Serialize + ?Sized,
{
val.serialize(&mut Serializer::new(wr))
}
/// Serialize the given data structure as MessagePack into the I/O stream. /// This function serializes structures as maps /// /// Serialization can fail if `T`'s implementation of `Serialize` decides to fail. pubfn write_named<W, T>(wr: &mut W, val: &T) -> Result<(), Error> where
W: Write + ?Sized,
T: Serialize + ?Sized,
{ letmut se = Serializer::new(wr); // Avoids another monomorphisation of `StructMapConfig`
se.config = RuntimeConfig::new(StructMapConfig::new(se.config));
val.serialize(&mut se)
}
/// Serialize the given data structure as a MessagePack byte vector. /// This method uses compact representation, structs are serialized as arrays /// /// Serialization can fail if `T`'s implementation of `Serialize` decides to fail. #[inline] pubfn to_vec<T>(val: &T) -> Result<Vec<u8>, Error> where
T: Serialize + ?Sized,
{ letmut wr = FallibleWriter(Vec::new());
write(&mut wr, val)?;
Ok(wr.0)
}
/// Serializes data structure into byte vector as a map /// Resulting MessagePack message will contain field names /// /// # Errors /// /// Serialization can fail if `T`'s implementation of `Serialize` decides to fail. #[inline] pubfn to_vec_named<T>(val: &T) -> Result<Vec<u8>, Error> where
T: Serialize + ?Sized,
{ letmut wr = FallibleWriter(Vec::new());
write_named(&mut wr, val)?;
Ok(wr.0)
}
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.