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