1use core::mem::MaybeUninit;
4use core::{fmt, str};
5
6use serde::ser;
7use serde::ser::SerializeStruct as _;
8use serde::Serialize;
9
10#[cfg(feature = "heapless")]
11use heapless::{String, Vec};
12
13use self::map::SerializeMap;
14use self::seq::SerializeSeq;
15use self::struct_::{SerializeStruct, SerializeStructVariant};
16
17mod map;
18mod seq;
19mod struct_;
20
21pub type Result<T> = ::core::result::Result<T, Error>;
23
24#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize)]
26#[cfg_attr(feature = "defmt", derive(defmt::Format))]
27#[non_exhaustive]
28pub enum Error {
29 BufferFull,
31}
32
33impl From<()> for Error {
34 fn from(_: ()) -> Error {
35 Error::BufferFull
36 }
37}
38
39impl From<u8> for Error {
40 fn from(_: u8) -> Error {
41 Error::BufferFull
42 }
43}
44
45#[cfg(feature = "heapless")]
46impl From<heapless::CapacityError> for Error {
47 fn from(_: heapless::CapacityError) -> Self {
48 Error::BufferFull
49 }
50}
51
52impl serde::ser::StdError for Error {}
53
54impl fmt::Display for Error {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 write!(f, "Buffer is full")
57 }
58}
59
60pub struct Serializer<'a> {
62 buf: &'a mut [u8],
63 current_length: usize,
64}
65
66impl<'a> Serializer<'a> {
67 pub fn new(buf: &'a mut [u8]) -> Self {
69 Serializer {
70 buf,
71 current_length: 0,
72 }
73 }
74
75 pub fn end(&self) -> usize {
77 self.current_length
78 }
79
80 fn push(&mut self, c: u8) -> Result<()> {
81 if self.current_length < self.buf.len() {
82 unsafe { self.push_unchecked(c) };
83 Ok(())
84 } else {
85 Err(Error::BufferFull)
86 }
87 }
88
89 unsafe fn push_unchecked(&mut self, c: u8) {
90 self.buf[self.current_length] = c;
91 self.current_length += 1;
92 }
93
94 fn extend_from_slice(&mut self, other: &[u8]) -> Result<()> {
95 if self.current_length + other.len() > self.buf.len() {
96 Err(Error::BufferFull)
98 } else {
99 for c in other {
100 unsafe { self.push_unchecked(*c) };
101 }
102 Ok(())
103 }
104 }
105
106 fn push_char(&mut self, c: char) -> Result<()> {
107 let mut encoding_tmp = [0u8; 4];
118
119 match c {
120 '\\' => {
121 self.push(b'\\')?;
122 self.push(b'\\')?;
123 }
124 '"' => {
125 self.push(b'\\')?;
126 self.push(b'"')?;
127 }
128 '\u{0008}' => {
129 self.push(b'\\')?;
130 self.push(b'b')?;
131 }
132 '\u{0009}' => {
133 self.push(b'\\')?;
134 self.push(b't')?;
135 }
136 '\u{000A}' => {
137 self.push(b'\\')?;
138 self.push(b'n')?;
139 }
140 '\u{000C}' => {
141 self.push(b'\\')?;
142 self.push(b'f')?;
143 }
144 '\u{000D}' => {
145 self.push(b'\\')?;
146 self.push(b'r')?;
147 }
148 '\u{0000}'..='\u{001F}' => {
149 self.push(b'\\')?;
150 self.push(b'u')?;
151 self.push(b'0')?;
152 self.push(b'0')?;
153 let (hex1, hex2) = hex(c as u8);
154 self.push(hex1)?;
155 self.push(hex2)?;
156 }
157 _ => {
158 let encoded = c.encode_utf8(&mut encoding_tmp as &mut [u8]);
159 self.extend_from_slice(encoded.as_bytes())?;
160 }
161 }
162
163 Ok(())
164 }
165}
166
167macro_rules! serialize_unsigned {
170 ($self:ident, $N:expr, $v:expr) => {{
171 let mut buf: [MaybeUninit<u8>; $N] = [MaybeUninit::uninit(); $N];
172
173 let mut v = $v;
174 let mut i = $N - 1;
175 loop {
176 buf[i].write((v % 10) as u8 + b'0');
177 v /= 10;
178
179 if v == 0 {
180 break;
181 } else {
182 i -= 1;
183 }
184 }
185
186 let buf = unsafe { &*(&buf[i..] as *const _ as *const [u8]) };
188
189 $self.extend_from_slice(buf)
190 }};
191}
192
193macro_rules! serialize_signed {
194 ($self:ident, $N:expr, $v:expr, $ixx:ident, $uxx:ident) => {{
195 let v = $v;
196 let (signed, mut v) = if v == $ixx::MIN {
197 (true, $ixx::MAX as $uxx + 1)
198 } else if v < 0 {
199 (true, -v as $uxx)
200 } else {
201 (false, v as $uxx)
202 };
203
204 let mut buf: [MaybeUninit<u8>; $N] = [MaybeUninit::uninit(); $N];
205 let mut i = $N - 1;
206 loop {
207 buf[i].write((v % 10) as u8 + b'0');
208 v /= 10;
209
210 i -= 1;
211
212 if v == 0 {
213 break;
214 }
215 }
216
217 if signed {
218 buf[i].write(b'-');
219 } else {
220 i += 1;
221 }
222
223 let buf = unsafe { &*(&buf[i..] as *const _ as *const [u8]) };
225
226 $self.extend_from_slice(buf)
227 }};
228}
229
230macro_rules! serialize_ryu {
231 ($self:ident, $v:expr) => {{
232 let mut buffer = ryu::Buffer::new();
233 let printed = buffer.format($v);
234 $self.extend_from_slice(printed.as_bytes())
235 }};
236}
237
238fn hex_4bit(c: u8) -> u8 {
240 if c <= 9 {
241 0x30 + c
242 } else {
243 0x41 + (c - 10)
244 }
245}
246
247fn hex(c: u8) -> (u8, u8) {
249 (hex_4bit(c >> 4), hex_4bit(c & 0x0F))
250}
251
252impl<'a, 'b: 'a> ser::Serializer for &'a mut Serializer<'b> {
253 type Ok = ();
254 type Error = Error;
255 type SerializeSeq = SerializeSeq<'a, 'b>;
256 type SerializeTuple = SerializeSeq<'a, 'b>;
257 type SerializeTupleStruct = SerializeSeq<'a, 'b>;
258 type SerializeTupleVariant = Unreachable;
259 type SerializeMap = SerializeMap<'a, 'b>;
260 type SerializeStruct = SerializeStruct<'a, 'b>;
261 type SerializeStructVariant = SerializeStructVariant<'a, 'b>;
262
263 fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
264 if v {
265 self.extend_from_slice(b"true")
266 } else {
267 self.extend_from_slice(b"false")
268 }
269 }
270
271 fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
272 serialize_signed!(self, 4, v, i8, u8)
274 }
275
276 fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
277 serialize_signed!(self, 6, v, i16, u16)
279 }
280
281 fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
282 serialize_signed!(self, 11, v, i32, u32)
284 }
285
286 fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
287 serialize_signed!(self, 20, v, i64, u64)
289 }
290
291 fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
292 serialize_unsigned!(self, 3, v)
294 }
295
296 fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
297 serialize_unsigned!(self, 5, v)
299 }
300
301 fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
302 serialize_unsigned!(self, 10, v)
304 }
305
306 fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
307 serialize_unsigned!(self, 20, v)
309 }
310
311 fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
312 if v.is_finite() {
313 serialize_ryu!(self, v)
314 } else {
315 self.serialize_none()
316 }
317 }
318
319 fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
320 if v.is_finite() {
321 serialize_ryu!(self, v)
322 } else {
323 self.serialize_none()
324 }
325 }
326
327 fn serialize_char(self, _v: char) -> Result<Self::Ok> {
328 unreachable!()
329 }
330
331 fn serialize_str(self, v: &str) -> Result<Self::Ok> {
332 self.push(b'"')?;
333
334 for c in v.chars() {
335 self.push_char(c)?;
336 }
337
338 self.push(b'"')
339 }
340
341 fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
342 self.extend_from_slice(v)
343 }
344
345 fn serialize_none(self) -> Result<Self::Ok> {
346 self.extend_from_slice(b"null")
347 }
348
349 fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
350 where
351 T: ser::Serialize + ?Sized,
352 {
353 value.serialize(self)
354 }
355
356 fn serialize_unit(self) -> Result<Self::Ok> {
357 self.serialize_none()
358 }
359
360 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
361 self.serialize_unit()
362 }
363
364 fn serialize_unit_variant(
365 self,
366 _name: &'static str,
367 _variant_index: u32,
368 variant: &'static str,
369 ) -> Result<Self::Ok> {
370 self.serialize_str(variant)
371 }
372
373 fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<Self::Ok>
374 where
375 T: ser::Serialize + ?Sized,
376 {
377 if name == crate::str::EscapedStr::NAME {
379 struct EscapedStringSerializer<'a, 'b>(&'a mut Serializer<'b>);
382
383 impl<'a, 'b: 'a> serde::Serializer for EscapedStringSerializer<'a, 'b> {
384 type Ok = ();
385 type Error = Error;
386
387 type SerializeSeq = serde::ser::Impossible<(), Error>;
388 type SerializeTuple = serde::ser::Impossible<(), Error>;
389 type SerializeTupleStruct = serde::ser::Impossible<(), Error>;
390 type SerializeTupleVariant = serde::ser::Impossible<(), Error>;
391 type SerializeMap = serde::ser::Impossible<(), Error>;
392 type SerializeStruct = serde::ser::Impossible<(), Error>;
393 type SerializeStructVariant = serde::ser::Impossible<(), Error>;
394
395 fn serialize_bool(self, _v: bool) -> Result<Self::Ok> {
396 unreachable!()
397 }
398
399 fn serialize_i8(self, _v: i8) -> Result<Self::Ok> {
400 unreachable!()
401 }
402
403 fn serialize_i16(self, _v: i16) -> Result<Self::Ok> {
404 unreachable!()
405 }
406
407 fn serialize_i32(self, _v: i32) -> Result<Self::Ok> {
408 unreachable!()
409 }
410
411 fn serialize_i64(self, _v: i64) -> Result<Self::Ok> {
412 unreachable!()
413 }
414
415 fn serialize_u8(self, _v: u8) -> Result<Self::Ok> {
416 unreachable!()
417 }
418
419 fn serialize_u16(self, _v: u16) -> Result<Self::Ok> {
420 unreachable!()
421 }
422
423 fn serialize_u32(self, _v: u32) -> Result<Self::Ok> {
424 unreachable!()
425 }
426
427 fn serialize_u64(self, _v: u64) -> Result<Self::Ok> {
428 unreachable!()
429 }
430
431 fn serialize_f32(self, _v: f32) -> Result<Self::Ok> {
432 unreachable!()
433 }
434
435 fn serialize_f64(self, _v: f64) -> Result<Self::Ok> {
436 unreachable!()
437 }
438
439 fn serialize_char(self, _v: char) -> Result<Self::Ok> {
440 unreachable!()
441 }
442
443 fn serialize_str(self, v: &str) -> Result<Self::Ok> {
444 v.bytes().try_for_each(|c| self.0.push(c))
445 }
446
447 fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok> {
448 unreachable!()
449 }
450
451 fn serialize_none(self) -> Result<Self::Ok> {
452 unreachable!()
453 }
454
455 fn serialize_some<T: Serialize + ?Sized>(self, _value: &T) -> Result<Self::Ok> {
456 unreachable!()
457 }
458
459 fn serialize_unit(self) -> Result<Self::Ok> {
460 unreachable!()
461 }
462
463 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
464 unreachable!()
465 }
466
467 fn serialize_unit_variant(
468 self,
469 _name: &'static str,
470 _variant_index: u32,
471 _variant: &'static str,
472 ) -> Result<Self::Ok> {
473 unreachable!()
474 }
475
476 fn serialize_newtype_struct<T: Serialize + ?Sized>(
477 self,
478 _name: &'static str,
479 _value: &T,
480 ) -> Result<Self::Ok> {
481 unreachable!()
482 }
483
484 fn serialize_newtype_variant<T: Serialize + ?Sized>(
485 self,
486 _name: &'static str,
487 _variant_index: u32,
488 _variant: &'static str,
489 _value: &T,
490 ) -> Result<Self::Ok> {
491 unreachable!()
492 }
493
494 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
495 unreachable!()
496 }
497
498 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
499 unreachable!()
500 }
501
502 fn serialize_tuple_struct(
503 self,
504 _name: &'static str,
505 _len: usize,
506 ) -> Result<Self::SerializeTupleStruct> {
507 unreachable!()
508 }
509
510 fn serialize_tuple_variant(
511 self,
512 _name: &'static str,
513 _variant_index: u32,
514 _variant: &'static str,
515 _len: usize,
516 ) -> Result<Self::SerializeTupleVariant> {
517 unreachable!()
518 }
519
520 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
521 unreachable!()
522 }
523
524 fn serialize_struct(
525 self,
526 _name: &'static str,
527 _len: usize,
528 ) -> Result<Self::SerializeStruct> {
529 unreachable!()
530 }
531
532 fn serialize_struct_variant(
533 self,
534 _name: &'static str,
535 _variant_index: u32,
536 _variant: &'static str,
537 _len: usize,
538 ) -> Result<Self::SerializeStructVariant> {
539 unreachable!()
540 }
541
542 fn collect_str<T: fmt::Display + ?Sized>(self, _value: &T) -> Result<Self::Ok> {
543 unreachable!()
544 }
545 }
546
547 self.push(b'"')?;
548
549 value.serialize(EscapedStringSerializer(self))?;
550
551 self.push(b'"')?;
552
553 Ok(())
554 } else {
555 value.serialize(self)
556 }
557 }
558
559 fn serialize_newtype_variant<T>(
560 self,
561 _name: &'static str,
562 _variant_index: u32,
563 variant: &'static str,
564 value: &T,
565 ) -> Result<Self::Ok>
566 where
567 T: ser::Serialize + ?Sized,
568 {
569 self.push(b'{')?;
570 let mut s = SerializeStruct::new(self);
571 s.serialize_field(variant, value)?;
572 s.end()?;
573 Ok(())
574 }
575
576 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
577 self.push(b'[')?;
578
579 Ok(SerializeSeq::new(self))
580 }
581
582 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
583 self.serialize_seq(Some(_len))
584 }
585
586 fn serialize_tuple_struct(
587 self,
588 _name: &'static str,
589 len: usize,
590 ) -> Result<Self::SerializeTupleStruct> {
591 self.serialize_seq(Some(len))
592 }
593
594 fn serialize_tuple_variant(
595 self,
596 _name: &'static str,
597 _variant_index: u32,
598 _variant: &'static str,
599 _len: usize,
600 ) -> Result<Self::SerializeTupleVariant> {
601 unreachable!()
602 }
603
604 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
605 self.push(b'{')?;
606
607 Ok(SerializeMap::new(self))
608 }
609
610 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
611 self.push(b'{')?;
612
613 Ok(SerializeStruct::new(self))
614 }
615
616 fn serialize_struct_variant(
617 self,
618 _name: &'static str,
619 _variant_index: u32,
620 variant: &'static str,
621 _len: usize,
622 ) -> Result<Self::SerializeStructVariant> {
623 self.extend_from_slice(b"{\"")?;
624 self.extend_from_slice(variant.as_bytes())?;
625 self.extend_from_slice(b"\":{")?;
626
627 Ok(SerializeStructVariant::new(self))
628 }
629
630 fn collect_str<T>(self, value: &T) -> Result<Self::Ok>
631 where
632 T: fmt::Display + ?Sized,
633 {
634 self.push(b'"')?;
635
636 let mut col = StringCollector::new(self);
637 fmt::write(&mut col, format_args!("{}", value)).or(Err(Error::BufferFull))?;
638
639 self.push(b'"')
640 }
641}
642
643struct StringCollector<'a, 'b> {
644 ser: &'a mut Serializer<'b>,
645}
646
647impl<'a, 'b> StringCollector<'a, 'b> {
648 pub fn new(ser: &'a mut Serializer<'b>) -> Self {
649 Self { ser }
650 }
651
652 fn do_write_str(&mut self, s: &str) -> Result<()> {
653 for c in s.chars() {
654 self.ser.push_char(c)?;
655 }
656
657 Ok(())
658 }
659}
660
661impl fmt::Write for StringCollector<'_, '_> {
662 fn write_str(&mut self, s: &str) -> fmt::Result {
663 self.do_write_str(s).or(Err(fmt::Error))
664 }
665}
666
667#[cfg(feature = "heapless")]
669pub fn to_string<T, const N: usize>(value: &T) -> Result<String<N>>
670where
671 T: ser::Serialize + ?Sized,
672{
673 Ok(unsafe { String::from_utf8_unchecked(to_vec::<T, N>(value)?) })
674}
675
676#[cfg(feature = "heapless")]
678pub fn to_vec<T, const N: usize>(value: &T) -> Result<Vec<u8, N>>
679where
680 T: ser::Serialize + ?Sized,
681{
682 let mut buf = Vec::<u8, N>::new();
683 buf.resize_default(N)?;
684 let len = to_slice(value, &mut buf)?;
685 buf.truncate(len);
686 Ok(buf)
687}
688
689pub fn to_slice<T>(value: &T, buf: &mut [u8]) -> Result<usize>
691where
692 T: ser::Serialize + ?Sized,
693{
694 let mut ser = Serializer::new(buf);
695 value.serialize(&mut ser)?;
696 Ok(ser.current_length)
697}
698
699impl ser::Error for Error {
700 fn custom<T>(_msg: T) -> Self
701 where
702 T: fmt::Display,
703 {
704 unreachable!()
705 }
706}
707
708pub enum Unreachable {}
710
711impl ser::SerializeTupleVariant for Unreachable {
712 type Ok = ();
713 type Error = Error;
714
715 fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<()> {
716 unreachable!()
717 }
718
719 fn end(self) -> Result<Self::Ok> {
720 unreachable!()
721 }
722}
723
724#[cfg(test)]
725mod tests {
726 use serde_derive::Serialize;
727
728 const N: usize = 128;
729
730 #[test]
731 fn array() {
732 let buf = &mut [0u8; 128];
733 let len = crate::to_slice(&[0, 1, 2], buf).unwrap();
734 assert_eq!(len, 7);
735 assert_eq!(&buf[..len], b"[0,1,2]");
736 assert_eq!(&*crate::to_string::<_, N>(&[0, 1, 2]).unwrap(), "[0,1,2]");
737 }
738
739 #[test]
740 fn bool() {
741 let buf = &mut [0u8; 128];
742 let len = crate::to_slice(&true, buf).unwrap();
743 assert_eq!(len, 4);
744 assert_eq!(&buf[..len], b"true");
745
746 assert_eq!(&*crate::to_string::<_, N>(&true).unwrap(), "true");
747 }
748
749 #[test]
750 fn enum_() {
751 #[derive(Serialize)]
752 enum Type {
753 #[serde(rename = "boolean")]
754 Boolean,
755 #[serde(rename = "number")]
756 Number,
757 }
758
759 assert_eq!(
760 &*crate::to_string::<_, N>(&Type::Boolean).unwrap(),
761 r#""boolean""#
762 );
763
764 assert_eq!(
765 &*crate::to_string::<_, N>(&Type::Number).unwrap(),
766 r#""number""#
767 );
768 }
769
770 #[test]
771 fn str() {
772 assert_eq!(&*crate::to_string::<_, N>("hello").unwrap(), r#""hello""#);
773 assert_eq!(&*crate::to_string::<_, N>("").unwrap(), r#""""#);
774
775 assert_eq!(&*crate::to_string::<_, N>("ä").unwrap(), r#""ä""#);
777 assert_eq!(&*crate::to_string::<_, N>("৬").unwrap(), r#""৬""#);
778 assert_eq!(&*crate::to_string::<_, N>("ℝ").unwrap(), r#""ℝ""#); assert_eq!(&*crate::to_string::<_, N>("💣").unwrap(), r#""💣""#); assert_eq!(
784 &*crate::to_string::<_, N>("foo\"bar").unwrap(),
785 r#""foo\"bar""#
786 );
787 assert_eq!(
788 &*crate::to_string::<_, N>("foo\\bar").unwrap(),
789 r#""foo\\bar""#
790 );
791
792 assert_eq!(
794 &*crate::to_string::<_, N>(" \u{0008} ").unwrap(),
795 r#"" \b ""#
796 );
797 assert_eq!(
798 &*crate::to_string::<_, N>(" \u{0009} ").unwrap(),
799 r#"" \t ""#
800 );
801 assert_eq!(
802 &*crate::to_string::<_, N>(" \u{000A} ").unwrap(),
803 r#"" \n ""#
804 );
805 assert_eq!(
806 &*crate::to_string::<_, N>(" \u{000C} ").unwrap(),
807 r#"" \f ""#
808 );
809 assert_eq!(
810 &*crate::to_string::<_, N>(" \u{000D} ").unwrap(),
811 r#"" \r ""#
812 );
813
814 assert_eq!(
816 &*crate::to_string::<_, N>(" \u{0000} ").unwrap(),
817 r#"" \u0000 ""#
818 );
819 assert_eq!(
820 &*crate::to_string::<_, N>(" \u{0001} ").unwrap(),
821 r#"" \u0001 ""#
822 );
823 assert_eq!(
824 &*crate::to_string::<_, N>(" \u{0007} ").unwrap(),
825 r#"" \u0007 ""#
826 );
827 assert_eq!(
828 &*crate::to_string::<_, N>(" \u{000e} ").unwrap(),
829 r#"" \u000E ""#
830 );
831 assert_eq!(
832 &*crate::to_string::<_, N>(" \u{001D} ").unwrap(),
833 r#"" \u001D ""#
834 );
835 assert_eq!(
836 crate::to_string::<_, N>(" \u{001f} ").unwrap(),
837 r#"" \u001F ""#
838 );
839 }
840
841 #[test]
842 fn escaped_str() {
843 assert_eq!(
844 crate::to_string::<_, N>(&crate::str::EscapedStr(r#"Hello\\nWorld"#)).unwrap(),
845 r#""Hello\\nWorld""#
846 );
847 }
848
849 #[test]
850 fn struct_bool() {
851 #[derive(Serialize)]
852 struct Led {
853 led: bool,
854 }
855
856 assert_eq!(
857 &*crate::to_string::<_, N>(&Led { led: true }).unwrap(),
858 r#"{"led":true}"#
859 );
860 }
861
862 #[test]
863 fn struct_i8() {
864 #[derive(Serialize)]
865 struct Temperature {
866 temperature: i8,
867 }
868
869 assert_eq!(
870 &*crate::to_string::<_, N>(&Temperature { temperature: 127 }).unwrap(),
871 r#"{"temperature":127}"#
872 );
873
874 assert_eq!(
875 &*crate::to_string::<_, N>(&Temperature { temperature: 20 }).unwrap(),
876 r#"{"temperature":20}"#
877 );
878
879 assert_eq!(
880 &*crate::to_string::<_, N>(&Temperature { temperature: -17 }).unwrap(),
881 r#"{"temperature":-17}"#
882 );
883
884 assert_eq!(
885 &*crate::to_string::<_, N>(&Temperature { temperature: -128 }).unwrap(),
886 r#"{"temperature":-128}"#
887 );
888 }
889
890 #[test]
891 fn struct_f32() {
892 #[derive(Serialize)]
893 struct Temperature {
894 temperature: f32,
895 }
896
897 assert_eq!(
898 &*crate::to_string::<_, N>(&Temperature { temperature: -20. }).unwrap(),
899 r#"{"temperature":-20.0}"#
900 );
901
902 assert_eq!(
903 &*crate::to_string::<_, N>(&Temperature {
904 temperature: -20345.
905 })
906 .unwrap(),
907 r#"{"temperature":-20345.0}"#
908 );
909
910 assert_eq!(
911 &*crate::to_string::<_, N>(&Temperature {
912 temperature: -2.345_678_8e-23
913 })
914 .unwrap(),
915 r#"{"temperature":-2.3456788e-23}"#
916 );
917
918 assert_eq!(
919 &*crate::to_string::<_, N>(&Temperature {
920 temperature: f32::NAN
921 })
922 .unwrap(),
923 r#"{"temperature":null}"#
924 );
925
926 assert_eq!(
927 &*crate::to_string::<_, N>(&Temperature {
928 temperature: f32::NEG_INFINITY
929 })
930 .unwrap(),
931 r#"{"temperature":null}"#
932 );
933 }
934
935 #[test]
936 fn struct_option() {
937 #[derive(Serialize)]
938 struct Property<'a> {
939 description: Option<&'a str>,
940 }
941
942 assert_eq!(
943 crate::to_string::<_, N>(&Property {
944 description: Some("An ambient temperature sensor"),
945 })
946 .unwrap(),
947 r#"{"description":"An ambient temperature sensor"}"#
948 );
949
950 assert_eq!(
952 crate::to_string::<_, N>(&Property { description: None }).unwrap(),
953 r#"{"description":null}"#
954 );
955 }
956
957 #[test]
958 fn struct_u8() {
959 #[derive(Serialize)]
960 struct Temperature {
961 temperature: u8,
962 }
963
964 assert_eq!(
965 &*crate::to_string::<_, N>(&Temperature { temperature: 20 }).unwrap(),
966 r#"{"temperature":20}"#
967 );
968 }
969
970 #[test]
971 fn struct_() {
972 #[derive(Serialize)]
973 struct Empty {}
974
975 assert_eq!(&*crate::to_string::<_, N>(&Empty {}).unwrap(), r#"{}"#);
976
977 #[derive(Serialize)]
978 struct Tuple {
979 a: bool,
980 b: bool,
981 }
982
983 assert_eq!(
984 &*crate::to_string::<_, N>(&Tuple { a: true, b: false }).unwrap(),
985 r#"{"a":true,"b":false}"#
986 );
987 }
988
989 #[test]
990 fn test_unit() {
991 let a = ();
992 assert_eq!(&*crate::to_string::<_, N>(&a).unwrap(), r#"null"#);
993 }
994
995 #[test]
996 fn test_newtype_struct() {
997 #[derive(Serialize)]
998 struct A(pub u32);
999 let a = A(54);
1000 assert_eq!(&*crate::to_string::<_, N>(&a).unwrap(), r#"54"#);
1001 }
1002
1003 #[test]
1004 fn test_newtype_variant() {
1005 #[derive(Serialize)]
1006 enum A {
1007 A(u32),
1008 }
1009 let a = A::A(54);
1010
1011 assert_eq!(&*crate::to_string::<_, N>(&a).unwrap(), r#"{"A":54}"#);
1012 }
1013
1014 #[test]
1015 fn test_struct_variant() {
1016 #[derive(Serialize)]
1017 enum A {
1018 A { x: u32, y: u16 },
1019 }
1020 let a = A::A { x: 54, y: 720 };
1021
1022 assert_eq!(
1023 &*crate::to_string::<_, N>(&a).unwrap(),
1024 r#"{"A":{"x":54,"y":720}}"#
1025 );
1026 }
1027
1028 #[test]
1029 fn test_tuple_struct() {
1030 #[derive(Serialize)]
1031 struct A<'a>(u32, Option<&'a str>, u16, bool);
1032
1033 let a = A(42, Some("A string"), 720, false);
1034
1035 assert_eq!(
1036 &*crate::to_string::<_, N>(&a).unwrap(),
1037 r#"[42,"A string",720,false]"#
1038 );
1039 }
1040
1041 #[test]
1042 fn test_tuple_struct_roundtrip() {
1043 use serde_derive::Deserialize;
1044
1045 #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
1046 struct A<'a>(u32, Option<&'a str>, u16, bool);
1047
1048 let a1 = A(42, Some("A string"), 720, false);
1049 let serialized = crate::to_string::<_, N>(&a1).unwrap();
1050 let (a2, _size): (A<'_>, usize) = crate::from_str(&serialized).unwrap();
1051 assert_eq!(a1, a2);
1052 }
1053
1054 #[test]
1055 fn test_serialize_bytes() {
1056 use core::fmt::Write;
1057 use heapless::String;
1058
1059 pub struct SimpleDecimal(f32);
1060
1061 impl serde::Serialize for SimpleDecimal {
1062 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1063 where
1064 S: serde::Serializer,
1065 {
1066 let mut aux: String<{ N }> = String::new();
1067 write!(aux, "{:.2}", self.0).unwrap();
1068 serializer.serialize_bytes(aux.as_bytes())
1069 }
1070 }
1071
1072 let sd1 = SimpleDecimal(1.55555);
1073 assert_eq!(&*crate::to_string::<_, N>(&sd1).unwrap(), r#"1.56"#);
1074
1075 let sd2 = SimpleDecimal(0.000);
1076 assert_eq!(&*crate::to_string::<_, N>(&sd2).unwrap(), r#"0.00"#);
1077
1078 let sd3 = SimpleDecimal(22_222.777);
1079 assert_eq!(&*crate::to_string::<_, N>(&sd3).unwrap(), r#"22222.78"#);
1080 }
1081}