1use crate::error::{Error, Result};
2use serde::{ser, Serialize};
3use std::io::Write;
4
5#[inline]
7pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
8where
9 W: Write,
10 T: Serialize + ?Sized,
11{
12 let mut ser = Serializer::new(writer);
13 value.serialize(&mut ser)
14}
15
16#[inline]
18pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
19where
20 T: Serialize + ?Sized,
21{
22 let mut buf = Vec::new();
23 to_writer(&mut buf, value)?;
24 Ok(buf)
25}
26
27#[derive(Debug)]
29struct Serializer<W> {
30 output: W,
31}
32
33impl<W> Serializer<W> {
34 #[inline]
36 fn new(output: W) -> Self {
37 Serializer { output }
38 }
39}
40
41#[derive(Debug)]
46struct NotImplemented;
47
48impl<'a, W> ser::Serializer for &'a mut Serializer<W>
49where
50 W: Write,
51{
52 type Ok = ();
53
54 type Error = Error;
55
56 type SerializeSeq = NumericArraySerializer<'a, W>;
57 type SerializeTuple = NumericArraySerializer<'a, W>;
58 type SerializeTupleStruct = NumericArraySerializer<'a, W>;
59 type SerializeTupleVariant = NotImplemented;
60 type SerializeMap = Self;
61 type SerializeStruct = Self;
62 type SerializeStructVariant = NotImplemented;
63
64 #[inline]
65 fn serialize_bool(self, v: bool) -> Result<()> {
66 if v {
67 self.output.write_all(b"b:1;")
68 } else {
69 self.output.write_all(b"b:0;")
70 }
71 .map_err(Error::WriteSerialized)
72 }
73
74 #[inline]
75 fn serialize_i8(self, v: i8) -> Result<()> {
76 self.serialize_i64(i64::from(v))
77 }
78
79 #[inline]
80 fn serialize_i16(self, v: i16) -> Result<()> {
81 self.serialize_i64(i64::from(v))
82 }
83
84 #[inline]
85 fn serialize_i32(self, v: i32) -> Result<()> {
86 self.serialize_i64(i64::from(v))
87 }
88
89 #[inline]
90 fn serialize_i64(self, v: i64) -> Result<()> {
91 write!(self.output, "i:{};", v).map_err(Error::WriteSerialized)
94 }
95
96 #[inline]
97 fn serialize_u8(self, v: u8) -> Result<()> {
98 self.serialize_u64(u64::from(v))
99 }
100
101 #[inline]
102 fn serialize_u16(self, v: u16) -> Result<()> {
103 self.serialize_u64(u64::from(v))
104 }
105
106 #[inline]
107 fn serialize_u32(self, v: u32) -> Result<()> {
108 self.serialize_u64(u64::from(v))
109 }
110
111 #[inline]
112 fn serialize_u64(self, v: u64) -> Result<()> {
113 write!(self.output, "i:{};", v).map_err(Error::WriteSerialized)
114 }
115
116 #[inline]
117 fn serialize_f32(self, v: f32) -> Result<()> {
118 self.serialize_f64(f64::from(v))
119 }
120
121 #[inline]
122 fn serialize_f64(self, v: f64) -> Result<()> {
123 write!(self.output, "d:{};", v).map_err(Error::WriteSerialized)
126 }
127
128 #[inline]
129 fn serialize_char(self, v: char) -> Result<()> {
130 self.serialize_u32(u32::from(v))
131 }
132
133 #[inline]
134 fn serialize_str(self, v: &str) -> Result<()> {
135 self.serialize_bytes(v.as_bytes())
136 }
137
138 #[inline]
139 fn serialize_bytes(self, v: &[u8]) -> Result<()> {
140 write!(self.output, "s:{}:\"", v.len()).map_err(Error::WriteSerialized)?;
141 self.output.write_all(v).map_err(Error::WriteSerialized)?;
142 write!(self.output, "\";").map_err(Error::WriteSerialized)
143 }
144
145 #[inline]
146 fn serialize_none(self) -> Result<()> {
147 self.serialize_unit()
148 }
149
150 #[inline]
151 fn serialize_some<T>(self, value: &T) -> Result<()>
152 where
153 T: ?Sized + Serialize,
154 {
155 value.serialize(self)
156 }
157
158 #[inline]
159 fn serialize_unit(self) -> Result<()> {
160 self.output.write_all(b"N;").map_err(Error::WriteSerialized)
161 }
162
163 #[inline]
164 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
165 Err(Error::MissingFeature(
166 "Serialization of unit structures is not supported.",
167 ))
168 }
169
170 #[inline]
171 fn serialize_unit_variant(
172 self,
173 _name: &'static str,
174 _variant_index: u32,
175 _variant: &'static str,
176 ) -> Result<()> {
177 Err(Error::MissingFeature(
178 "Serialization of enums is not supported. If you need C-style enums serialized, look at `serde_repr`.",
179 ))
180 }
181
182 #[inline]
183 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
184 where
185 T: ?Sized + Serialize,
186 {
187 value.serialize(self)
189 }
190
191 #[inline]
192 fn serialize_newtype_variant<T>(
193 self,
194 _name: &'static str,
195 _variant_index: u32,
196 _variant: &'static str,
197 _value: &T,
198 ) -> Result<()>
199 where
200 T: ?Sized + Serialize,
201 {
202 Err(Error::MissingFeature(
203 "Serialization of enums is not supported. If you need C-style enums serialized, look at `serde_repr`.",
204 ))
205 }
206
207 #[inline]
208 fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
209 if let Some(n) = len {
217 write!(self.output, "a:{}:{{", n).map_err(Error::WriteSerialized)?;
219 Ok(NumericArraySerializer::new(self))
220 } else {
221 Err(Error::LengthRequired)
222 }
223 }
224
225 #[inline]
226 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
227 self.serialize_seq(Some(len))
228 }
229
230 #[inline]
231 fn serialize_tuple_struct(
232 self,
233 _name: &'static str,
234 len: usize,
235 ) -> Result<Self::SerializeTupleStruct> {
236 self.serialize_tuple(len)
237 }
238
239 #[inline]
240 fn serialize_tuple_variant(
241 self,
242 _name: &'static str,
243 _variant_index: u32,
244 _variant: &'static str,
245 _len: usize,
246 ) -> Result<Self::SerializeTupleVariant> {
247 Err(Error::MissingFeature(
248 "Serialization of enums is not supported. If you need C-style enums serialized, look at `serde_repr`.",
249 ))
250 }
251
252 #[inline]
253 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
254 if let Some(n) = len {
255 write!(self.output, "a:{}:{{", n).map_err(Error::WriteSerialized)?;
256 Ok(self)
258 } else {
259 Err(Error::LengthRequired)
260 }
261 }
262
263 #[inline]
264 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
265 self.serialize_map(Some(len))
266 }
267
268 #[inline]
269 fn serialize_struct_variant(
270 self,
271 _name: &'static str,
272 _variant_index: u32,
273 _variant: &'static str,
274 _len: usize,
275 ) -> Result<Self::SerializeStructVariant> {
276 Err(Error::MissingFeature(
277 "Serialization of enums is not supported. If you need C-style enums serialized, look at `serde_repr`.",
278 ))
279 }
280}
281
282#[derive(Debug)]
284pub struct NumericArraySerializer<'a, W> {
285 index: usize,
289 serializer: &'a mut Serializer<W>,
290}
291
292impl<'a, W> NumericArraySerializer<'a, W> {
293 fn new(serializer: &'a mut Serializer<W>) -> Self {
295 NumericArraySerializer {
296 index: 0,
297 serializer,
298 }
299 }
300}
301
302impl<'a, W> ser::SerializeSeq for NumericArraySerializer<'a, W>
303where
304 W: Write,
305{
306 type Ok = ();
307 type Error = Error;
308
309 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
310 where
311 T: ?Sized + Serialize,
312 {
313 self.index.serialize(&mut *self.serializer)?;
315 value.serialize(&mut *self.serializer)?;
316 self.index += 1;
317 Ok(())
318 }
319
320 fn end(self) -> Result<()> {
321 self.serializer
322 .output
323 .write_all(b"}")
324 .map_err(Error::WriteSerialized)
325 }
326}
327
328impl<'a, W> ser::SerializeTuple for NumericArraySerializer<'a, W>
329where
330 W: Write,
331{
332 type Ok = ();
333 type Error = Error;
334
335 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
336 where
337 T: ?Sized + Serialize,
338 {
339 ser::SerializeSeq::serialize_element(self, value)
340 }
341
342 fn end(self) -> Result<()> {
343 ser::SerializeSeq::end(self)
344 }
345}
346
347impl<'a, W> ser::SerializeTupleStruct for NumericArraySerializer<'a, W>
348where
349 W: Write,
350{
351 type Ok = ();
352 type Error = Error;
353
354 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
355 where
356 T: ?Sized + Serialize,
357 {
358 ser::SerializeSeq::serialize_element(self, value)
359 }
360
361 fn end(self) -> Result<()> {
362 ser::SerializeSeq::end(self)
363 }
364}
365
366impl ser::SerializeTupleVariant for NotImplemented {
367 type Ok = ();
368 type Error = Error;
369
370 fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
371 where
372 T: ?Sized + Serialize,
373 {
374 Err(Error::MissingFeature(
375 "Serialization of enums is not supported. If you need C-style enums serialized, look at `serde_repr`.",
376 ))
377 }
378
379 fn end(self) -> Result<()> {
380 Err(Error::MissingFeature(
381 "Serialization of enums is not supported. If you need C-style enums serialized, look at `serde_repr`.",
382 ))
383 }
384}
385
386impl<'a, W> ser::SerializeMap for &'a mut Serializer<W>
387where
388 W: Write,
389{
390 type Ok = ();
391 type Error = Error;
392
393 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
394 where
395 T: ?Sized + Serialize,
396 {
397 key.serialize(&mut **self)
398 }
399
400 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
401 where
402 T: ?Sized + Serialize,
403 {
404 value.serialize(&mut **self)
405 }
406
407 fn end(self) -> Result<()> {
408 self.output.write_all(b"}").map_err(Error::WriteSerialized)
409 }
410}
411
412impl<'a, W> ser::SerializeStruct for &'a mut Serializer<W>
413where
414 W: Write,
415{
416 type Ok = ();
417 type Error = Error;
418
419 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
420 where
421 T: ?Sized + Serialize,
422 {
423 key.serialize(&mut **self)?;
424 value.serialize(&mut **self)?;
425 Ok(())
426 }
427
428 fn end(self) -> Result<()> {
429 self.output.write_all(b"}").map_err(Error::WriteSerialized)
430 }
431}
432
433impl ser::SerializeStructVariant for NotImplemented {
434 type Ok = ();
435 type Error = Error;
436
437 fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<()>
438 where
439 T: ?Sized + Serialize,
440 {
441 Err(Error::MissingFeature(
442 "Serialization of enums is not supported. If you need C-style enums serialized, look at `serde_repr`.",
443 ))
444 }
445
446 fn end(self) -> Result<()> {
447 Err(Error::MissingFeature(
448 "Serialization of enums is not supported. If you need C-style enums serialized, look at `serde_repr`.",
449 ))
450 }
451}
452
453#[cfg(test)]
454mod tests {
455 use super::to_vec;
456 use serde::Serialize;
457 use std::collections::BTreeMap;
458
459 macro_rules! assert_serializes {
460 ($v:expr, $expected:expr) => {
461 let actual = to_vec(&$v).expect("serialization failed");
462
463 eprintln!("{}", String::from_utf8_lossy(actual.as_slice()));
464 eprintln!("{}", String::from_utf8_lossy($expected));
465
466 assert_eq!(actual.as_slice(), &$expected[..]);
467 };
468 }
469
470 #[test]
471 fn serialize_unit() {
472 assert_serializes!((), b"N;");
473 }
474
475 #[test]
476 fn serialize_bool() {
477 assert_serializes!(false, b"b:0;");
478 assert_serializes!(true, b"b:1;");
479 }
480
481 #[test]
482 fn serialize_integer() {
483 assert_serializes!(-1i64, b"i:-1;");
484 assert_serializes!(0i64, b"i:0;");
485 assert_serializes!(1i64, b"i:1;");
486 assert_serializes!(123i64, b"i:123;");
487 }
488
489 #[test]
490 fn serialize_float() {
491 assert_serializes!(-1f64, b"d:-1;");
492 assert_serializes!(0f64, b"d:0;");
493 assert_serializes!(1f64, b"d:1;");
494 assert_serializes!(-1.9f64, b"d:-1.9;");
495 assert_serializes!(0.9f64, b"d:0.9;");
496 assert_serializes!(1.9f64, b"d:1.9;");
497 }
498
499 #[test]
500 fn serialize_php_string() {
501 assert_serializes!(
502 serde_bytes::Bytes::new(b"single quote '"),
503 br#"s:14:"single quote '";"#
504 );
505
506 assert_serializes!(
507 serde_bytes::ByteBuf::from(b"single quote '".to_vec()),
508 br#"s:14:"single quote '";"#
509 );
510 }
511
512 #[test]
513 fn serialize_string() {
514 assert_serializes!("single quote '", br#"s:14:"single quote '";"#);
515 assert_serializes!("single quote '".to_owned(), br#"s:14:"single quote '";"#);
516 }
517
518 #[test]
519 fn serialize_array() {
520 #[derive(Debug, Serialize, Eq, PartialEq)]
521 struct SubData();
522
523 #[derive(Debug, Serialize, Eq, PartialEq)]
524 struct Data(
525 #[serde(with = "serde_bytes")] Vec<u8>,
526 #[serde(with = "serde_bytes")] Vec<u8>,
527 SubData,
528 );
529
530 assert_serializes!(
531 Data(b"user".to_vec(), b"".to_vec(), SubData()),
532 br#"a:3:{i:0;s:4:"user";i:1;s:0:"";i:2;a:0:{}}"#
533 );
534 }
535
536 #[test]
537 fn serialize_struct() {
538 #[derive(Debug, Serialize, Eq, PartialEq)]
545 struct Outer {
546 foo: bool,
547 bar: String,
548 sub: Inner,
549 }
550
551 #[derive(Debug, Serialize, Eq, PartialEq)]
552 struct Inner {
553 x: i64,
554 }
555
556 assert_serializes!(
557 Outer {
558 foo: true,
559 bar: "xyz".to_owned(),
560 sub: Inner { x: 42 },
561 },
562 br#"a:3:{s:3:"foo";b:1;s:3:"bar";s:3:"xyz";s:3:"sub";a:1:{s:1:"x";i:42;}}"#
563 );
564 }
565
566 #[test]
567 fn serialize_struct_with_optional() {
568 #[derive(Debug, Serialize, Eq, PartialEq)]
569 struct Location {
570 #[serde(skip_serializing_if = "Option::is_none")]
571 province: Option<String>,
572 #[serde(skip_serializing_if = "Option::is_none")]
573 postalcode: Option<String>,
574 #[serde(skip_serializing_if = "Option::is_none")]
575 country: Option<String>,
576 }
577
578 assert_serializes!(
579 Location {
580 province: None,
581 postalcode: None,
582 country: None,
583 },
584 br#"a:0:{}"#
585 );
586
587 assert_serializes!(
588 Location {
589 province: Some("Newfoundland and Labrador, CA".to_owned()),
590 postalcode: None,
591 country: None,
592 },
593 br#"a:1:{s:8:"province";s:29:"Newfoundland and Labrador, CA";}"#
594 );
595
596 assert_serializes!(
597 Location {
598 province: None,
599 postalcode: Some("90002".to_owned()),
600 country: Some("United States of America".to_owned()),
601 },
602 br#"a:2:{s:10:"postalcode";s:5:"90002";s:7:"country";s:24:"United States of America";}"#
603 );
604 }
605
606 #[test]
607 fn serialize_nested() {
608 #[derive(Debug, Serialize, Eq, PartialEq)]
611 struct Outer {
612 x: Inner,
613 y: Inner,
614 }
615
616 #[derive(Debug, Serialize, Eq, PartialEq)]
617 struct Inner {
618 inner: u8,
619 }
620
621 assert_serializes!(
622 Outer {
623 x: Inner { inner: 1 },
624 y: Inner { inner: 2 },
625 },
626 br#"a:2:{s:1:"x";a:1:{s:5:"inner";i:1;}s:1:"y";a:1:{s:5:"inner";i:2;}}"#
627 );
628 }
629
630 #[test]
631 fn serialize_variable_length() {
632 assert_serializes!(
634 vec![1.1, 2.2, 3.3, 4.4],
635 br#"a:4:{i:0;d:1.1;i:1;d:2.2;i:2;d:3.3;i:3;d:4.4;}"#
636 );
637 }
638
639 #[test]
640 fn serialize_btreemap() {
641 let mut input: BTreeMap<String, u16> = BTreeMap::new();
643 input.insert("foo".to_owned(), 42);
644 input.insert("bar".to_owned(), 7);
645
646 assert_serializes!(input, br#"a:2:{s:3:"bar";i:7;s:3:"foo";i:42;}"#);
647 }
648
649 #[test]
650 fn unaffected_by_recursive_type_error() {
651 let val: bson::Bson = bson::Document::new().into();
662 to_vec(&val).unwrap();
663 }
664}