Skip to content

Commit d66e6ca

Browse files
committed
Add TimestampSerde for serde impl
1 parent bac67df commit d66e6ca

File tree

6 files changed

+339
-4
lines changed

6 files changed

+339
-4
lines changed

rmp-serde/src/decode.rs

+37-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rmp::decode::{self, DecodeStringError, MarkerReadError, NumValueReadError, R
2121
use rmp::Marker;
2222

2323
use crate::config::{BinaryConfig, DefaultConfig, HumanReadableConfig, SerializerConfig};
24-
use crate::MSGPACK_EXT_STRUCT_NAME;
24+
use crate::{MSGPACK_EXT_STRUCT_NAME, MSGPACK_TIMESTAMP_STRUCT_NAME};
2525

2626
/// Enum representing errors that can occur while decoding MessagePack data.
2727
#[derive(Debug)]
@@ -698,6 +698,11 @@ impl<'de, 'a, R: ReadSlice<'de>, C: SerializerConfig> serde::Deserializer<'de> f
698698
return visitor.visit_newtype_struct(ext_de);
699699
}
700700

701+
if name == MSGPACK_TIMESTAMP_STRUCT_NAME {
702+
let ts_de = TimestampDeserializer::new(&mut self.rd);
703+
return ts_de.deserialize_any(visitor);
704+
}
705+
701706
visitor.visit_newtype_struct(self)
702707
}
703708

@@ -1191,3 +1196,34 @@ where
11911196
let mut de = Deserializer::from_read_ref(rd);
11921197
Deserialize::deserialize(&mut de)
11931198
}
1199+
1200+
#[derive(Debug)]
1201+
pub(crate) struct TimestampDeserializer<'a, R> {
1202+
rd: &'a mut R,
1203+
}
1204+
1205+
impl<'a, R: Read> TimestampDeserializer<'a, R> {
1206+
pub(crate) fn new(rd: &'a mut R) -> Self {
1207+
Self {
1208+
rd,
1209+
}
1210+
}
1211+
}
1212+
1213+
impl<'de, 'a, R: Read> de::Deserializer<'de> for TimestampDeserializer<'a, R> {
1214+
type Error = Error;
1215+
1216+
fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
1217+
where
1218+
V: Visitor<'de> {
1219+
let ts = rmp::decode::read_timestamp(&mut self.rd)?;
1220+
1221+
visitor.visit_u128(ts.into_u128())
1222+
}
1223+
1224+
forward_to_deserialize_any! {
1225+
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
1226+
seq bytes byte_buf map unit_struct newtype_struct
1227+
struct identifier tuple enum ignored_any tuple_struct
1228+
}
1229+
}

rmp-serde/src/encode.rs

+191-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rmp::{encode, Marker};
2020
use crate::config::{
2121
BinaryConfig, DefaultConfig, HumanReadableConfig, RuntimeConfig, SerializerConfig, StructMapConfig, StructTupleConfig
2222
};
23-
use crate::MSGPACK_EXT_STRUCT_NAME;
23+
use crate::{MSGPACK_EXT_STRUCT_NAME, MSGPACK_TIMESTAMP_STRUCT_NAME};
2424

2525
/// This type represents all possible errors that can occur when serializing or
2626
/// deserializing MessagePack data.
@@ -685,6 +685,13 @@ where
685685
return ext_se.end();
686686
}
687687

688+
if name == MSGPACK_TIMESTAMP_STRUCT_NAME {
689+
let mut ts_se = TimestampSerializer::new(&mut self.wr);
690+
value.serialize(&mut ts_se)?;
691+
692+
return Ok(());
693+
}
694+
688695
// Encode as if it's inner type.
689696
value.serialize(self)
690697
}
@@ -1269,3 +1276,186 @@ impl Write for FallibleWriter {
12691276
Ok(())
12701277
}
12711278
}
1279+
1280+
struct TimestampSerializer<'a, W> {
1281+
wr: &'a mut W
1282+
}
1283+
1284+
impl<'a, W: Write> TimestampSerializer<'a, W> {
1285+
fn new(wr: &'a mut W) -> Self {
1286+
Self { wr }
1287+
}
1288+
}
1289+
1290+
impl<'a, W: Write> serde::Serializer for &'a mut TimestampSerializer<'a, W> {
1291+
type Ok = ();
1292+
1293+
type Error = Error;
1294+
1295+
type SerializeSeq = serde::ser::Impossible<(), Error>;
1296+
type SerializeTuple = serde::ser::Impossible<(), Error>;
1297+
type SerializeTupleStruct = serde::ser::Impossible<(), Error>;
1298+
type SerializeTupleVariant = serde::ser::Impossible<(), Error>;
1299+
type SerializeMap = serde::ser::Impossible<(), Error>;
1300+
type SerializeStruct = serde::ser::Impossible<(), Error>;
1301+
type SerializeStructVariant = serde::ser::Impossible<(), Error>;
1302+
1303+
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
1304+
let ts = rmp::Timestamp::from_u128(v).ok_or_else(|| Error::Syntax(format!("Not a valid Timestamp")))?;
1305+
rmp::encode::write_timestamp(self.wr, ts).map_err(|_| Error::Syntax(format!("Not a valid Timestamp")))?;
1306+
Ok(())
1307+
}
1308+
1309+
fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
1310+
Err(Error::InvalidDataModel("expected u128"))
1311+
}
1312+
1313+
fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
1314+
Err(Error::InvalidDataModel("expected u128"))
1315+
}
1316+
1317+
fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
1318+
Err(Error::InvalidDataModel("expected u128"))
1319+
}
1320+
1321+
fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
1322+
Err(Error::InvalidDataModel("expected u128"))
1323+
}
1324+
1325+
fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
1326+
Err(Error::InvalidDataModel("expected u128"))
1327+
}
1328+
1329+
fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
1330+
Err(Error::InvalidDataModel("expected u128"))
1331+
}
1332+
1333+
fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
1334+
Err(Error::InvalidDataModel("expected u128"))
1335+
}
1336+
1337+
fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
1338+
Err(Error::InvalidDataModel("expected u128"))
1339+
}
1340+
1341+
fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
1342+
Err(Error::InvalidDataModel("expected u128"))
1343+
}
1344+
1345+
fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
1346+
Err(Error::InvalidDataModel("expected u128"))
1347+
}
1348+
1349+
fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
1350+
Err(Error::InvalidDataModel("expected u128"))
1351+
}
1352+
1353+
fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
1354+
Err(Error::InvalidDataModel("expected u128"))
1355+
}
1356+
1357+
fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> {
1358+
Err(Error::InvalidDataModel("expected u128"))
1359+
}
1360+
1361+
fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
1362+
Err(Error::InvalidDataModel("expected u128"))
1363+
}
1364+
1365+
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
1366+
Err(Error::InvalidDataModel("expected u128"))
1367+
}
1368+
1369+
fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
1370+
where
1371+
T: ?Sized + Serialize {
1372+
Err(Error::InvalidDataModel("expected u128"))
1373+
}
1374+
1375+
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
1376+
Err(Error::InvalidDataModel("expected u128"))
1377+
}
1378+
1379+
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
1380+
Err(Error::InvalidDataModel("expected u128"))
1381+
}
1382+
1383+
fn serialize_unit_variant(
1384+
self,
1385+
_name: &'static str,
1386+
_variant_index: u32,
1387+
_variant: &'static str,
1388+
) -> Result<Self::Ok, Self::Error> {
1389+
Err(Error::InvalidDataModel("expected u128"))
1390+
}
1391+
1392+
fn serialize_newtype_struct<T>(
1393+
self,
1394+
_name: &'static str,
1395+
_value: &T,
1396+
) -> Result<Self::Ok, Self::Error>
1397+
where
1398+
T: ?Sized + Serialize {
1399+
Err(Error::InvalidDataModel("expected u128"))
1400+
}
1401+
1402+
fn serialize_newtype_variant<T>(
1403+
self,
1404+
_name: &'static str,
1405+
_variant_index: u32,
1406+
_variant: &'static str,
1407+
_value: &T,
1408+
) -> Result<Self::Ok, Self::Error>
1409+
where
1410+
T: ?Sized + Serialize {
1411+
Err(Error::InvalidDataModel("expected u128"))
1412+
}
1413+
1414+
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
1415+
Err(Error::InvalidDataModel("expected u128"))
1416+
}
1417+
1418+
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
1419+
Err(Error::InvalidDataModel("expected u128"))
1420+
}
1421+
1422+
fn serialize_tuple_struct(
1423+
self,
1424+
_name: &'static str,
1425+
_len: usize,
1426+
) -> Result<Self::SerializeTupleStruct, Self::Error> {
1427+
Err(Error::InvalidDataModel("expected u128"))
1428+
}
1429+
1430+
fn serialize_tuple_variant(
1431+
self,
1432+
_name: &'static str,
1433+
_variant_index: u32,
1434+
_variant: &'static str,
1435+
_len: usize,
1436+
) -> Result<Self::SerializeTupleVariant, Self::Error> {
1437+
Err(Error::InvalidDataModel("expected u128"))
1438+
}
1439+
1440+
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
1441+
Err(Error::InvalidDataModel("expected u128"))
1442+
}
1443+
1444+
fn serialize_struct(
1445+
self,
1446+
_name: &'static str,
1447+
_len: usize,
1448+
) -> Result<Self::SerializeStruct, Self::Error> {
1449+
Err(Error::InvalidDataModel("expected u128"))
1450+
}
1451+
1452+
fn serialize_struct_variant(
1453+
self,
1454+
_name: &'static str,
1455+
_variant_index: u32,
1456+
_variant: &'static str,
1457+
_len: usize,
1458+
) -> Result<Self::SerializeStructVariant, Self::Error> {
1459+
Err(Error::InvalidDataModel("expected u128"))
1460+
}
1461+
}

rmp-serde/src/lib.rs

+48
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub mod encode;
4040
/// Value::Ext(2, vec![5]));
4141
/// ```
4242
pub const MSGPACK_EXT_STRUCT_NAME: &str = "_ExtStruct";
43+
pub(crate) const MSGPACK_TIMESTAMP_STRUCT_NAME: &str = "_TimestampForInternalUseOnly";
4344

4445
/// Helper that allows both to encode and decode strings no matter whether they contain valid or
4546
/// invalid UTF-8.
@@ -335,3 +336,50 @@ impl<'de> Deserialize<'de> for RawRef<'de> {
335336
de.deserialize_any(RawRefVisitor)
336337
}
337338
}
339+
340+
/// This is a wrapper for `rmp::Timestamp` which is only used for serde.
341+
///
342+
/// This maps to the serde data model as follows:
343+
///
344+
/// `struct _TimestampForInternalUseOnly(u128);`
345+
///
346+
/// This will encode enough information for the Serializer and Deserializer
347+
/// to properly manage the data to and from the msgpack format.
348+
///
349+
/// This wrapper should ONLY be used with the msgpack Serializer and Deserializer
350+
/// from this library.
351+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
352+
pub struct TimestampSerde(pub rmp::Timestamp);
353+
354+
impl Serialize for TimestampSerde {
355+
fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
356+
where
357+
S: serde::Serializer,
358+
{
359+
se.serialize_newtype_struct(MSGPACK_TIMESTAMP_STRUCT_NAME, &self.0.into_u128())
360+
}
361+
}
362+
363+
impl<'de> Deserialize<'de> for TimestampSerde {
364+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
365+
where
366+
D: de::Deserializer<'de>,
367+
{
368+
struct TimestampVisitor;
369+
370+
impl de::Visitor<'_> for TimestampVisitor {
371+
type Value = TimestampSerde;
372+
373+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
374+
formatter.write_str("A valid TimestampSerde")
375+
}
376+
377+
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
378+
where
379+
E: de::Error, {
380+
Ok(TimestampSerde(rmp::Timestamp::from_u128(v).ok_or_else(|| de::Error::custom("invalid TimestampSerde"))?))
381+
}
382+
}
383+
deserializer.deserialize_newtype_struct(MSGPACK_TIMESTAMP_STRUCT_NAME, TimestampVisitor)
384+
}
385+
}

rmp-serde/tests/decode_derive.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::io::Cursor;
33
use serde::Deserialize;
44

55
use rmp_serde::decode::Error;
6-
use rmp_serde::Deserializer;
6+
use rmp_serde::{Deserializer, TimestampSerde};
77

88
#[test]
99
fn pass_newtype() {
@@ -66,6 +66,24 @@ fn pass_struct() {
6666
assert_eq!(Decoded { id: 42, value: 100500 }, actual);
6767
}
6868

69+
#[test]
70+
fn pass_timestamp() {
71+
let buf = [0x93, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94, 0xd6, 0xff, 0x0, 0x0, 0x0, 0x7];
72+
let cur = Cursor::new(&buf[..]);
73+
74+
#[derive(Debug, PartialEq, Deserialize)]
75+
struct Decoded {
76+
id: u32,
77+
value: u32,
78+
ts: TimestampSerde,
79+
}
80+
81+
let mut de = Deserializer::new(cur);
82+
let actual: Decoded = Deserialize::deserialize(&mut de).unwrap();
83+
84+
assert_eq!(Decoded { id: 42, value: 100500, ts: TimestampSerde(rmp::Timestamp::from_32(7)) }, actual);
85+
}
86+
6987
#[test]
7088
fn pass_struct_from_map() {
7189
#[derive(Debug, PartialEq, Deserialize)]

rmp-serde/tests/encode_derive.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rmp_serde::Serializer;
1+
use rmp_serde::{Serializer, TimestampSerde};
22
use serde::Serialize;
33

44
#[test]
@@ -129,6 +129,27 @@ fn pass_struct() {
129129
assert_eq!(vec![0x92, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94], buf);
130130
}
131131

132+
#[test]
133+
fn pass_timestamp() {
134+
#[derive(Serialize)]
135+
struct Struct {
136+
f1: u32,
137+
f2: u32,
138+
ts: TimestampSerde,
139+
}
140+
141+
let val = Struct {
142+
f1: 42,
143+
f2: 100500,
144+
ts: TimestampSerde(rmp::Timestamp::from_32(9))
145+
};
146+
let mut buf = Vec::new();
147+
val.serialize(&mut Serializer::new(&mut buf)).unwrap();
148+
149+
// Expect: [42, 100500, 4 byte Timestamp].
150+
assert_eq!(vec![0x93, 0x2a, 0xce, 0x0, 0x1, 0x88, 0x94, 0xd6, 0xff, 0x0, 0x0, 0x0, 0x9], buf);
151+
}
152+
132153
#[test]
133154
fn serialize_struct_variant() {
134155
#[derive(Serialize)]

0 commit comments

Comments
 (0)