1use core::{fmt, mem};
4
5use serde::ser;
6
7use heapless::{String, Vec};
8
9use self::seq::SerializeSeq;
10use self::struct_::SerializeStruct;
11
12mod seq;
13mod struct_;
14
15pub type Result<T> = ::core::result::Result<T, Error>;
17
18#[derive(Debug)]
20pub enum Error {
21 BufferFull,
23 #[doc(hidden)]
24 __Extensible,
25}
26
27impl From<()> for Error {
28 fn from(_: ()) -> Error {
29 Error::BufferFull
30 }
31}
32
33impl From<u8> for Error {
34 fn from(_: u8) -> Error {
35 Error::BufferFull
36 }
37}
38
39#[cfg(feature = "std")]
40impl ::std::error::Error for Error {
41 fn description(&self) -> &str {
42 ""
43 }
44}
45
46impl fmt::Display for Error {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 write!(f, "Buffer is full")
49 }
50}
51
52pub(crate) struct Serializer<B>
53where
54 B: heapless::ArrayLength<u8>,
55{
56 buf: Vec<u8, B>,
57}
58
59impl<B> Serializer<B>
60where
61 B: heapless::ArrayLength<u8>,
62{
63 fn new() -> Self {
64 Serializer { buf: Vec::new() }
65 }
66}
67
68macro_rules! serialize_unsigned {
71 ($self:ident, $N:expr, $v:expr) => {{
72 let mut buf: [u8; $N] = unsafe { mem::MaybeUninit::uninit().assume_init() };
73
74 let mut v = $v;
75 let mut i = $N - 1;
76 loop {
77 buf[i] = (v % 10) as u8 + b'0';
78 v /= 10;
79
80 if v == 0 {
81 break;
82 } else {
83 i -= 1;
84 }
85 }
86
87 $self.buf.extend_from_slice(&buf[i..])?;
88 Ok(())
89 }};
90}
91
92macro_rules! serialize_signed {
93 ($self:ident, $N:expr, $v:expr, $ixx:ident, $uxx:ident) => {{
94 let v = $v;
95 let (signed, mut v) = if v == $ixx::min_value() {
96 (true, $ixx::max_value() as $uxx + 1)
97 } else if v < 0 {
98 (true, -v as $uxx)
99 } else {
100 (false, v as $uxx)
101 };
102
103 let mut buf: [u8; $N] = unsafe { mem::MaybeUninit::uninit().assume_init() };
104 let mut i = $N - 1;
105 loop {
106 buf[i] = (v % 10) as u8 + b'0';
107 v /= 10;
108
109 i -= 1;
110
111 if v == 0 {
112 break;
113 }
114 }
115
116 if signed {
117 buf[i] = b'-';
118 } else {
119 i += 1;
120 }
121 $self.buf.extend_from_slice(&buf[i..])?;
122 Ok(())
123 }};
124}
125
126impl<'a, B> ser::Serializer for &'a mut Serializer<B>
127where
128 B: heapless::ArrayLength<u8>,
129{
130 type Ok = ();
131 type Error = Error;
132 type SerializeSeq = SerializeSeq<'a, B>;
133 type SerializeTuple = SerializeSeq<'a, B>;
134 type SerializeTupleStruct = Unreachable;
135 type SerializeTupleVariant = Unreachable;
136 type SerializeMap = Unreachable;
137 type SerializeStruct = SerializeStruct<'a, B>;
138 type SerializeStructVariant = Unreachable;
139
140 fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
141 if v {
142 self.buf.extend_from_slice(b"true")?;
143 } else {
144 self.buf.extend_from_slice(b"false")?;
145 }
146
147 Ok(())
148 }
149
150 fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
151 serialize_signed!(self, 4, v, i8, u8)
153 }
154
155 fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
156 serialize_signed!(self, 6, v, i16, u16)
158 }
159
160 fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
161 serialize_signed!(self, 11, v, i32, u32)
163 }
164
165 fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
166 serialize_signed!(self, 20, v, i64, u64)
168 }
169
170 fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
171 serialize_unsigned!(self, 3, v)
173 }
174
175 fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
176 serialize_unsigned!(self, 5, v)
178 }
179
180 fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
181 serialize_unsigned!(self, 10, v)
183 }
184
185 fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
186 serialize_unsigned!(self, 20, v)
188 }
189
190 fn serialize_f32(self, _v: f32) -> Result<Self::Ok> {
191 unreachable!()
192 }
193
194 fn serialize_f64(self, _v: f64) -> Result<Self::Ok> {
195 unreachable!()
196 }
197
198 fn serialize_char(self, _v: char) -> Result<Self::Ok> {
199 unreachable!()
200 }
201
202 fn serialize_str(self, v: &str) -> Result<Self::Ok> {
203 self.buf.push(b'"')?;
204 self.buf.extend_from_slice(v.as_bytes())?;
205 self.buf.push(b'"')?;
206 Ok(())
207 }
208
209 fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok> {
210 unreachable!()
211 }
212
213 fn serialize_none(self) -> Result<Self::Ok> {
214 self.buf.extend_from_slice(b"null")?;
215 Ok(())
216 }
217
218 fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok>
219 where
220 T: ser::Serialize,
221 {
222 value.serialize(self)
223 }
224
225 fn serialize_unit(self) -> Result<Self::Ok> {
226 unreachable!()
227 }
228
229 fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
230 unreachable!()
231 }
232
233 fn serialize_unit_variant(
234 self,
235 _name: &'static str,
236 _variant_index: u32,
237 variant: &'static str,
238 ) -> Result<Self::Ok> {
239 self.serialize_str(variant)
240 }
241
242 fn serialize_newtype_struct<T: ?Sized>(
243 self,
244 _name: &'static str,
245 _value: &T,
246 ) -> Result<Self::Ok>
247 where
248 T: ser::Serialize,
249 {
250 unreachable!()
251 }
252
253 fn serialize_newtype_variant<T: ?Sized>(
254 self,
255 _name: &'static str,
256 _variant_index: u32,
257 _variant: &'static str,
258 _value: &T,
259 ) -> Result<Self::Ok>
260 where
261 T: ser::Serialize,
262 {
263 unreachable!()
264 }
265
266 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
267 self.buf.push(b'[')?;
268
269 Ok(SerializeSeq::new(self))
270 }
271
272 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
273 self.serialize_seq(Some(_len))
274 }
275
276 fn serialize_tuple_struct(
277 self,
278 _name: &'static str,
279 _len: usize,
280 ) -> Result<Self::SerializeTupleStruct> {
281 unreachable!()
282 }
283
284 fn serialize_tuple_variant(
285 self,
286 _name: &'static str,
287 _variant_index: u32,
288 _variant: &'static str,
289 _len: usize,
290 ) -> Result<Self::SerializeTupleVariant> {
291 unreachable!()
292 }
293
294 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
295 unreachable!()
296 }
297
298 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
299 self.buf.push(b'{')?;
300
301 Ok(SerializeStruct::new(self))
302 }
303
304 fn serialize_struct_variant(
305 self,
306 _name: &'static str,
307 _variant_index: u32,
308 _variant: &'static str,
309 _len: usize,
310 ) -> Result<Self::SerializeStructVariant> {
311 unreachable!()
312 }
313
314 fn collect_str<T: ?Sized>(self, _value: &T) -> Result<Self::Ok>
315 where
316 T: fmt::Display,
317 {
318 unreachable!()
319 }
320}
321
322pub fn to_string<B, T>(value: &T) -> Result<String<B>>
324where
325 B: heapless::ArrayLength<u8>,
326 T: ser::Serialize + ?Sized,
327{
328 let mut ser = Serializer::new();
329 value.serialize(&mut ser)?;
330 Ok(unsafe { String::from_utf8_unchecked(ser.buf) })
331}
332
333pub fn to_vec<B, T>(value: &T) -> Result<Vec<u8, B>>
335where
336 B: heapless::ArrayLength<u8>,
337 T: ser::Serialize + ?Sized,
338{
339 let mut ser = Serializer::new();
340 value.serialize(&mut ser)?;
341 Ok(ser.buf)
342}
343
344impl ser::Error for Error {
345 fn custom<T>(_msg: T) -> Self
346 where
347 T: fmt::Display,
348 {
349 unreachable!()
350 }
351}
352
353pub(crate) enum Unreachable {}
354
355impl ser::SerializeTupleStruct for Unreachable {
356 type Ok = ();
357 type Error = Error;
358
359 fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<()> {
360 unreachable!()
361 }
362
363 fn end(self) -> Result<Self::Ok> {
364 unreachable!()
365 }
366}
367
368impl ser::SerializeTupleVariant for Unreachable {
369 type Ok = ();
370 type Error = Error;
371
372 fn serialize_field<T: ?Sized>(&mut self, _value: &T) -> Result<()> {
373 unreachable!()
374 }
375
376 fn end(self) -> Result<Self::Ok> {
377 unreachable!()
378 }
379}
380
381impl ser::SerializeMap for Unreachable {
382 type Ok = ();
383 type Error = Error;
384
385 fn serialize_key<T: ?Sized>(&mut self, _key: &T) -> Result<()>
386 where
387 T: ser::Serialize,
388 {
389 unreachable!()
390 }
391
392 fn serialize_value<T: ?Sized>(&mut self, _value: &T) -> Result<()>
393 where
394 T: ser::Serialize,
395 {
396 unreachable!()
397 }
398
399 fn end(self) -> Result<Self::Ok> {
400 unreachable!()
401 }
402}
403
404impl ser::SerializeStructVariant for Unreachable {
405 type Ok = ();
406 type Error = Error;
407
408 fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, _value: &T) -> Result<()>
409 where
410 T: ser::Serialize,
411 {
412 unreachable!()
413 }
414
415 fn end(self) -> Result<Self::Ok> {
416 unreachable!()
417 }
418}
419
420#[cfg(test)]
421mod tests {
422 use serde_derive::Serialize;
423
424 use heapless::consts::U128;
425
426 type N = U128;
427
428 #[test]
429 fn array() {
430 assert_eq!(&*crate::to_string::<N, _>(&[0, 1, 2]).unwrap(), "[0,1,2]");
431 }
432
433 #[test]
434 fn bool() {
435 assert_eq!(&*crate::to_string::<N, _>(&true).unwrap(), "true");
436 }
437
438 #[test]
439 fn enum_() {
440 #[derive(Serialize)]
441 enum Type {
442 #[serde(rename = "boolean")]
443 Boolean,
444 #[serde(rename = "number")]
445 Number,
446 }
447
448 assert_eq!(
449 &*crate::to_string::<N, _>(&Type::Boolean).unwrap(),
450 r#""boolean""#
451 );
452
453 assert_eq!(
454 &*crate::to_string::<N, _>(&Type::Number).unwrap(),
455 r#""number""#
456 );
457 }
458
459 #[test]
460 fn str() {
461 assert_eq!(&*crate::to_string::<N, _>("hello").unwrap(), r#""hello""#);
462 }
463
464 #[test]
465 fn struct_bool() {
466 #[derive(Serialize)]
467 struct Led {
468 led: bool,
469 }
470
471 assert_eq!(
472 &*crate::to_string::<N, _>(&Led { led: true }).unwrap(),
473 r#"{"led":true}"#
474 );
475 }
476
477 #[test]
478 fn struct_i8() {
479 #[derive(Serialize)]
480 struct Temperature {
481 temperature: i8,
482 }
483
484 assert_eq!(
485 &*crate::to_string::<N, _>(&Temperature { temperature: 127 }).unwrap(),
486 r#"{"temperature":127}"#
487 );
488
489 assert_eq!(
490 &*crate::to_string::<N, _>(&Temperature { temperature: 20 }).unwrap(),
491 r#"{"temperature":20}"#
492 );
493
494 assert_eq!(
495 &*crate::to_string::<N, _>(&Temperature { temperature: -17 }).unwrap(),
496 r#"{"temperature":-17}"#
497 );
498
499 assert_eq!(
500 &*crate::to_string::<N, _>(&Temperature { temperature: -128 }).unwrap(),
501 r#"{"temperature":-128}"#
502 );
503 }
504
505 #[test]
506 fn struct_option() {
507 #[derive(Serialize)]
508 struct Property<'a> {
509 description: Option<&'a str>,
510 }
511
512 assert_eq!(
513 crate::to_string::<N, _>(&Property {
514 description: Some("An ambient temperature sensor"),
515 })
516 .unwrap(),
517 r#"{"description":"An ambient temperature sensor"}"#
518 );
519
520 assert_eq!(
522 crate::to_string::<N, _>(&Property { description: None }).unwrap(),
523 r#"{"description":null}"#
524 );
525 }
526
527 #[test]
528 fn struct_u8() {
529 #[derive(Serialize)]
530 struct Temperature {
531 temperature: u8,
532 }
533
534 assert_eq!(
535 &*crate::to_string::<N, _>(&Temperature { temperature: 20 }).unwrap(),
536 r#"{"temperature":20}"#
537 );
538 }
539
540 #[test]
541 fn struct_() {
542 #[derive(Serialize)]
543 struct Empty {}
544
545 assert_eq!(&*crate::to_string::<N, _>(&Empty {}).unwrap(), r#"{}"#);
546
547 #[derive(Serialize)]
548 struct Tuple {
549 a: bool,
550 b: bool,
551 }
552
553 assert_eq!(
554 &*crate::to_string::<N, _>(&Tuple { a: true, b: false }).unwrap(),
555 r#"{"a":true,"b":false}"#
556 );
557 }
558}