@@ -35,29 +35,32 @@ use std::ptr::NonNull;
35
35
use bincode:: Options ;
36
36
use bytes:: Buf ;
37
37
use bytes:: BufMut ;
38
- use bytes:: Bytes ;
39
38
use bytes:: buf:: UninitSlice ;
40
39
41
40
mod de;
42
41
mod part;
43
42
mod ser;
43
+ use bytes:: Bytes ;
44
44
use bytes:: BytesMut ;
45
45
use part:: Part ;
46
+ use serde:: Deserialize ;
47
+ use serde:: Serialize ;
46
48
47
49
/// A multi-part message, comprising a message body and a list of parts.
50
+ #[ derive( Debug , Clone , PartialEq , Eq , Serialize , Deserialize ) ]
48
51
pub struct Message {
49
- body : Bytes ,
52
+ body : Part ,
50
53
parts : Vec < Part > ,
51
54
}
52
55
53
56
impl Message {
54
57
/// Returns a new message with the given body and parts.
55
- pub fn from_body_and_parts ( body : Bytes , parts : Vec < Part > ) -> Self {
58
+ pub fn from_body_and_parts ( body : Part , parts : Vec < Part > ) -> Self {
56
59
Self { body, parts }
57
60
}
58
61
59
62
/// The body of the message.
60
- pub fn body ( & self ) -> & Bytes {
63
+ pub fn body ( & self ) -> & Part {
61
64
& self . body
62
65
}
63
66
@@ -66,19 +69,24 @@ impl Message {
66
69
& self . parts
67
70
}
68
71
69
- /// Returns the total number of parts (body + number of parts) in the message.
72
+ /// Returns the total number of parts (excluding the body) in the message.
73
+ pub fn num_parts ( & self ) -> usize {
74
+ self . parts . len ( )
75
+ }
76
+
77
+ /// Returns the total size (in bytes) of the message.
70
78
pub fn len ( & self ) -> usize {
71
- 1 + self . parts . len ( )
79
+ self . body . len ( ) + self . parts . iter ( ) . map ( |part| part . len ( ) ) . sum :: < usize > ( )
72
80
}
73
81
74
82
/// Returns whether the message is empty. It is always false, since the body
75
83
/// is always defined.
76
84
pub fn is_empty ( & self ) -> bool {
77
- false // there is always a body
85
+ self . body . is_empty ( ) && self . parts . iter ( ) . all ( |part| part . is_empty ( ) )
78
86
}
79
87
80
88
/// Convert this message into its constituent components.
81
- pub fn into_inner ( self ) -> ( Bytes , Vec < Part > ) {
89
+ pub fn into_inner ( self ) -> ( Part , Vec < Part > ) {
82
90
( self . body , self . parts )
83
91
}
84
92
}
@@ -144,30 +152,35 @@ unsafe impl BufMut for UnsafeBufCellRef {
144
152
///
145
153
/// Serialize uses the same codec options as [`bincode::serialize`] / [`bincode::deserialize`].
146
154
/// These are currently not customizable unless an explicit specialization is also provided.
147
- pub fn serialize < S : ?Sized + serde:: Serialize > ( value : & S ) -> Result < Message , bincode:: Error > {
155
+ pub fn serialize_bincode < S : ?Sized + serde:: Serialize > (
156
+ value : & S ,
157
+ ) -> Result < Message , bincode:: Error > {
148
158
let buffer = UnsafeBufCell :: from_bytes_mut ( BytesMut :: new ( ) ) ;
149
159
// SAFETY: we know here that, once the below "value.serialize()" is done, there are no more
150
160
// extant references to this buffer; we are thus safe to reclaim the buffer into the message
151
- let buffer_writer = unsafe { buffer. borrow_unchecked ( ) } ;
152
- let serializer = bincode :: Serializer :: new ( buffer_writer . writer ( ) , options ( ) ) ;
153
- let mut serializer : part :: BincodeSerializer = ser:: bincode:: Serializer :: new ( serializer ) ;
161
+ let buffer_borrow = unsafe { buffer. borrow_unchecked ( ) } ;
162
+ let mut serializer: part :: BincodeSerializer =
163
+ ser:: bincode:: Serializer :: new ( bincode :: Serializer :: new ( buffer_borrow . writer ( ) , options ( ) ) ) ;
154
164
value. serialize ( & mut serializer) ?;
155
165
Ok ( Message {
156
- body : buffer. into_inner ( ) . freeze ( ) ,
166
+ body : Part ( buffer. into_inner ( ) . freeze ( ) ) ,
157
167
parts : serializer. into_parts ( ) ,
158
168
} )
159
169
}
160
170
161
171
/// Deserialize a message serialized by `[serialize]`, stitching together the original
162
172
/// message without copying the underlying buffers.
163
- pub fn deserialize < ' a , T > ( message : Message ) -> Result < T , bincode:: Error >
173
+ pub fn deserialize_bincode < ' a , T > ( message : Message ) -> Result < T , bincode:: Error >
164
174
where
165
175
T : serde:: Deserialize < ' a > ,
166
176
{
167
177
let ( body, parts) = message. into_inner ( ) ;
168
- let bincode_deserializer = bincode:: Deserializer :: with_reader ( body. reader ( ) , options ( ) ) ;
169
- let mut deserializer = part:: BincodeDeserializer :: new ( bincode_deserializer, parts. into ( ) ) ;
178
+ let mut deserializer = part:: BincodeDeserializer :: new (
179
+ bincode:: Deserializer :: with_reader ( body. into_inner ( ) . reader ( ) , options ( ) ) ,
180
+ parts. into ( ) ,
181
+ ) ;
170
182
let value = T :: deserialize ( & mut deserializer) ?;
183
+ // Check that all parts were consumed:
171
184
deserializer. end ( ) ?;
172
185
Ok ( value)
173
186
}
@@ -193,9 +206,9 @@ mod tests {
193
206
where
194
207
T : Serialize + DeserializeOwned + PartialEq + std:: fmt:: Debug ,
195
208
{
196
- let message = serialize ( & value) . unwrap ( ) ;
197
- assert_eq ! ( message. len ( ) , expected_parts) ;
198
- let deserialized_value = deserialize ( message) . unwrap ( ) ;
209
+ let message = serialize_bincode ( & value) . unwrap ( ) ;
210
+ assert_eq ! ( message. num_parts ( ) , expected_parts) ;
211
+ let deserialized_value = deserialize_bincode ( message) . unwrap ( ) ;
199
212
assert_eq ! ( value, deserialized_value) ;
200
213
201
214
// Test normal bincode passthrough:
@@ -206,13 +219,13 @@ mod tests {
206
219
207
220
#[ test]
208
221
fn test_specialized_serializer_basic ( ) {
209
- test_roundtrip ( Part :: from ( "hello" ) , 2 ) ;
222
+ test_roundtrip ( Part :: from ( "hello" ) , 1 ) ;
210
223
}
211
224
212
225
#[ test]
213
226
fn test_specialized_serializer_compound ( ) {
214
- test_roundtrip ( vec ! [ Part :: from( "hello" ) , Part :: from( "world" ) ] , 3 ) ;
215
- test_roundtrip ( ( Part :: from ( "hello" ) , 1 , 2 , 3 , Part :: from ( "world" ) ) , 3 ) ;
227
+ test_roundtrip ( vec ! [ Part :: from( "hello" ) , Part :: from( "world" ) ] , 2 ) ;
228
+ test_roundtrip ( ( Part :: from ( "hello" ) , 1 , 2 , 3 , Part :: from ( "world" ) ) , 2 ) ;
216
229
test_roundtrip (
217
230
{
218
231
#[ derive( Serialize , Deserialize , Debug , PartialEq ) ]
@@ -242,7 +255,7 @@ mod tests {
242
255
] ,
243
256
}
244
257
} ,
245
- 8 ,
258
+ 7 ,
246
259
) ;
247
260
test_roundtrip (
248
261
{
@@ -262,29 +275,40 @@ mod tests {
262
275
field5 : 2 ,
263
276
}
264
277
} ,
265
- 3 ,
278
+ 2 ,
266
279
) ;
267
280
}
268
281
282
+ #[ test]
283
+ fn test_recursive_message ( ) {
284
+ let message = serialize_bincode ( & [ Part :: from ( "hello" ) , Part :: from ( "world" ) ] ) . unwrap ( ) ;
285
+ let message_message = serialize_bincode ( & message) . unwrap ( ) ;
286
+
287
+ // message.body + message.parts (x2):
288
+ assert_eq ! ( message_message. num_parts( ) , 3 ) ;
289
+ }
290
+
269
291
#[ test]
270
292
fn test_malformed_messages ( ) {
271
293
let message = Message {
272
- body : Bytes :: from_static ( b "hello") ,
294
+ body : Part :: from ( "hello" ) ,
273
295
parts : vec ! [ Part :: from( "world" ) ] ,
274
296
} ;
275
- let err = deserialize :: < String > ( message) . unwrap_err ( ) ;
297
+ let err = deserialize_bincode :: < String > ( message) . unwrap_err ( ) ;
276
298
277
299
// Normal bincode errors work:
278
300
assert_matches ! ( * err, bincode:: ErrorKind :: Io ( err) if err. kind( ) == std:: io:: ErrorKind :: UnexpectedEof ) ;
279
301
280
- let mut message = serialize ( & vec ! [ Part :: from( "hello" ) , Part :: from( "world" ) ] ) . unwrap ( ) ;
302
+ let mut message =
303
+ serialize_bincode ( & vec ! [ Part :: from( "hello" ) , Part :: from( "world" ) ] ) . unwrap ( ) ;
281
304
message. parts . push ( Part :: from ( "foo" ) ) ;
282
- let err = deserialize :: < Vec < Part > > ( message) . unwrap_err ( ) ;
305
+ let err = deserialize_bincode :: < Vec < Part > > ( message) . unwrap_err ( ) ;
283
306
assert_matches ! ( * err, bincode:: ErrorKind :: Custom ( message) if message == "multipart overrun while decoding" ) ;
284
307
285
- let mut message = serialize ( & vec ! [ Part :: from( "hello" ) , Part :: from( "world" ) ] ) . unwrap ( ) ;
308
+ let mut message =
309
+ serialize_bincode ( & vec ! [ Part :: from( "hello" ) , Part :: from( "world" ) ] ) . unwrap ( ) ;
286
310
let _dropped_message = message. parts . pop ( ) . unwrap ( ) ;
287
- let err = deserialize :: < Vec < Part > > ( message) . unwrap_err ( ) ;
311
+ let err = deserialize_bincode :: < Vec < Part > > ( message) . unwrap_err ( ) ;
288
312
assert_matches ! ( * err, bincode:: ErrorKind :: Custom ( message) if message == "multipart underrun while decoding" ) ;
289
313
}
290
314
}
0 commit comments