Skip to content

Commit b53139e

Browse files
committed
Add rmpv::ext::to_value_named to keep struct keys
The current `rmpv::ext::to_value` implementation turns Structs into `Value::Array<Value::String>` which is not deserializable by other languages. Technically I would call this a bug and opt to change the existing `to_value` implementation, but to stay cautious of not breaking existing users' code I think it makes sense to introduce a new `to_value_named` fn which instead turns Structs into `Value::Map` and maintains their keys.
1 parent 69f90c6 commit b53139e

File tree

2 files changed

+80
-13
lines changed

2 files changed

+80
-13
lines changed

rmpv/src/ext/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::{IntPriv, Integer, Value, ValueRef};
77

88
pub use self::de::{deserialize_from, from_value, EnumRefDeserializer};
99
pub use self::se::to_value;
10+
pub use self::se::to_value_named;
1011

1112
mod de;
1213
mod se;

rmpv/src/ext/se.rs

+79-13
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ impl ser::Error for Error {
6262
}
6363
}
6464

65-
struct Serializer;
65+
struct Serializer {
66+
named_structs: bool
67+
}
6668

6769
/// Convert a `T` into `rmpv::Value` which is an enum that can represent any valid MessagePack data.
6870
///
@@ -77,7 +79,27 @@ struct Serializer;
7779
/// ```
7880
#[inline]
7981
pub fn to_value<T: Serialize>(value: T) -> Result<Value, Error> {
80-
value.serialize(Serializer)
82+
value.serialize(Serializer {
83+
named_structs: false
84+
})
85+
}
86+
87+
/// The same as `rmpv::ext::to_value` with the variation that Structs are encoded as Value::Map
88+
///
89+
/// ```rust
90+
/// # use rmpv::Value;
91+
///
92+
/// struct Book { name: String }
93+
///
94+
/// let val = rmpv::ext::to_value_named(Book { name: "James".into() }).unwrap();
95+
///
96+
/// assert_eq!(Value::Map(vec![(Value::String("name"), Value::String("John Smith".into()))]), val);
97+
/// ```
98+
#[inline]
99+
pub fn to_value_named<T: Serialize>(value: T) -> Result<Value, Error> {
100+
value.serialize(Serializer {
101+
named_structs: true
102+
})
81103
}
82104

83105
impl ser::Serializer for Serializer {
@@ -89,7 +111,7 @@ impl ser::Serializer for Serializer {
89111
type SerializeTupleStruct = SerializeVec;
90112
type SerializeTupleVariant = SerializeTupleVariant;
91113
type SerializeMap = DefaultSerializeMap;
92-
type SerializeStruct = SerializeVec;
114+
type SerializeStruct = DefaultSerializeStruct;
93115
type SerializeStructVariant = SerializeStructVariant;
94116

95117
#[inline]
@@ -221,6 +243,7 @@ impl ser::Serializer for Serializer {
221243

222244
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
223245
let se = SerializeVec {
246+
named: self.named_structs,
224247
vec: Vec::with_capacity(len.unwrap_or(0))
225248
};
226249
Ok(se)
@@ -236,6 +259,7 @@ impl ser::Serializer for Serializer {
236259

237260
fn serialize_tuple_variant(self, _name: &'static str, idx: u32, _variant: &'static str, len: usize) -> Result<Self::SerializeTupleVariant, Error> {
238261
let se = SerializeTupleVariant {
262+
named: self.named_structs,
239263
idx,
240264
vec: Vec::with_capacity(len),
241265
};
@@ -244,20 +268,26 @@ impl ser::Serializer for Serializer {
244268

245269
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Error> {
246270
let se = DefaultSerializeMap {
271+
named: self.named_structs,
247272
map: Vec::with_capacity(len.unwrap_or(0)),
248273
next_key: None,
249274
};
250275
Ok(se)
251276
}
252277

253278
#[inline]
254-
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct, Error> {
255-
self.serialize_tuple_struct(name, len)
279+
fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct, Error> {
280+
let se = DefaultSerializeStruct {
281+
named: self.named_structs,
282+
map: Vec::with_capacity(len),
283+
};
284+
return Ok(se)
256285
}
257286

258287
#[inline]
259288
fn serialize_struct_variant(self, _name: &'static str, idx: u32, _variant: &'static str, len: usize) -> Result<Self::SerializeStructVariant, Error> {
260289
let se = SerializeStructVariant {
290+
named: self.named_structs,
261291
idx,
262292
vec: Vec::with_capacity(len),
263293
};
@@ -665,25 +695,35 @@ impl ExtFieldSerializer {
665695

666696
#[doc(hidden)]
667697
pub struct SerializeVec {
698+
named: bool,
668699
vec: Vec<Value>,
669700
}
670701

671702
/// Default implementation for tuple variant serialization. It packs given enums as a tuple of an
672703
/// index with a tuple of arguments.
673704
#[doc(hidden)]
674705
pub struct SerializeTupleVariant {
706+
named: bool,
675707
idx: u32,
676708
vec: Vec<Value>,
677709
}
678710

679711
#[doc(hidden)]
680712
pub struct DefaultSerializeMap {
713+
named: bool,
681714
map: Vec<(Value, Value)>,
682715
next_key: Option<Value>,
683716
}
684717

718+
#[doc(hidden)]
719+
pub struct DefaultSerializeStruct {
720+
named: bool,
721+
map: Vec<(Value, Value)>,
722+
}
723+
685724
#[doc(hidden)]
686725
pub struct SerializeStructVariant {
726+
named: bool,
687727
idx: u32,
688728
vec: Vec<Value>,
689729
}
@@ -696,7 +736,11 @@ impl SerializeSeq for SerializeVec {
696736
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
697737
where T: Serialize
698738
{
699-
self.vec.push(to_value(value)?);
739+
let value = match self.named {
740+
true => to_value_named(value)?,
741+
false => to_value(value)?,
742+
};
743+
self.vec.push(value);
700744
Ok(())
701745
}
702746

@@ -748,7 +792,11 @@ impl ser::SerializeTupleVariant for SerializeTupleVariant {
748792
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
749793
where T: Serialize
750794
{
751-
self.vec.push(to_value(value)?);
795+
let value = match self.named {
796+
true => to_value_named(value)?,
797+
false => to_value(value)?,
798+
};
799+
self.vec.push(value);
752800
Ok(())
753801
}
754802

@@ -777,7 +825,11 @@ impl ser::SerializeMap for DefaultSerializeMap {
777825
// expected failure.
778826
let key = self.next_key.take()
779827
.expect("`serialize_value` called before `serialize_key`");
780-
self.map.push((key, to_value(value)?));
828+
let value = match self.named {
829+
true => to_value_named(value)?,
830+
false => to_value(value)?,
831+
};
832+
self.map.push((key, value));
781833
Ok(())
782834
}
783835

@@ -787,20 +839,30 @@ impl ser::SerializeMap for DefaultSerializeMap {
787839
}
788840
}
789841

790-
impl SerializeStruct for SerializeVec {
842+
impl SerializeStruct for DefaultSerializeStruct {
791843
type Ok = Value;
792844
type Error = Error;
793845

794846
#[inline]
795-
fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<(), Error>
847+
fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
796848
where T: Serialize
797849
{
798-
ser::SerializeSeq::serialize_element(self, value)
850+
let value = match self.named {
851+
true => to_value_named(value)?,
852+
false => to_value(value)?,
853+
};
854+
self.map.push((to_value(key)?, value));
855+
Ok(())
799856
}
800857

801858
#[inline]
802859
fn end(self) -> Result<Value, Error> {
803-
ser::SerializeSeq::end(self)
860+
if self.named {
861+
return Ok(Value::Map(self.map))
862+
}
863+
864+
let stripped_keys: Vec<Value> = self.map.into_iter().map(|(_, val)| val).collect();
865+
Ok(Value::Array(stripped_keys))
804866
}
805867
}
806868

@@ -812,7 +874,11 @@ impl ser::SerializeStructVariant for SerializeStructVariant {
812874
fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<(), Error>
813875
where T: Serialize
814876
{
815-
self.vec.push(to_value(value)?);
877+
let value = match self.named {
878+
true => to_value_named(value)?,
879+
false => to_value(value)?,
880+
};
881+
self.vec.push(value);
816882
Ok(())
817883
}
818884

0 commit comments

Comments
 (0)