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