Skip to content

Commit 56fead2

Browse files
committed
Newtype & unit ser/de:
ser: * Added newtype serialization (as underlying value) * Added newtype_variant serialization (as object) * Added unit serialization (as null) der: * Added unit de * Added newtype_struct
1 parent 238c8fe commit 56fead2

File tree

4 files changed

+158
-19
lines changed

4 files changed

+158
-19
lines changed

.vscode/launch.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"type": "lldb",
9+
"request": "launch",
10+
"name": "Debug unit tests in library 'serde-json-core'",
11+
"cargo": {
12+
"args": [
13+
"test",
14+
"--no-run",
15+
"--lib",
16+
"--package=serde-json-core"
17+
],
18+
"filter": {
19+
"name": "serde-json-core",
20+
"kind": "lib"
21+
}
22+
},
23+
"args": [],
24+
"cwd": "${workspaceFolder}"
25+
}
26+
]
27+
}

src/de/mod.rs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -471,28 +471,40 @@ impl<'a, 'de> de::Deserializer<'de> for &'a mut Deserializer<'de> {
471471
}
472472
}
473473

474-
/// Unsupported. Use a more specific deserialize_* method
475-
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value>
474+
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
476475
where
477476
V: Visitor<'de>,
478477
{
479-
unreachable!()
478+
let peek = match self.parse_whitespace() {
479+
Some(b) => b,
480+
None => {
481+
return Err(Error::EofWhileParsingValue);
482+
}
483+
};
484+
485+
match peek {
486+
b'n' => {
487+
self.eat_char();
488+
self.parse_ident(b"ull")?;
489+
visitor.visit_unit()
490+
}
491+
_ => Err(Error::InvalidType),
492+
}
480493
}
481494

482-
/// Unsupported. Use a more specific deserialize_* method
483-
fn deserialize_unit_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value>
495+
fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
484496
where
485497
V: Visitor<'de>,
486498
{
487-
unreachable!()
499+
self.deserialize_unit(visitor)
488500
}
489501

490502
/// Unsupported. We can’t parse newtypes because we don’t know the underlying type.
491-
fn deserialize_newtype_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value>
503+
fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
492504
where
493505
V: Visitor<'de>,
494506
{
495-
unreachable!()
507+
visitor.visit_newtype_struct(self)
496508
}
497509

498510
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
@@ -878,6 +890,14 @@ mod tests {
878890
assert!(crate::from_str::<Temperature>(r#"{ "temperature": -1 }"#).is_err());
879891
}
880892

893+
#[test]
894+
fn newtype_struct() {
895+
#[derive(Deserialize, Debug, PartialEq)]
896+
struct A(pub u32);
897+
898+
assert_eq!(crate::from_str::<A>(r#"54"#).unwrap(), A(54));
899+
}
900+
881901
#[test]
882902
#[cfg(not(feature = "custom-error-messages"))]
883903
fn struct_tuple() {

src/ser/mod.rs

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
use core::{fmt, fmt::Write};
44

55
use serde::ser;
6+
use serde::ser::SerializeStruct as _;
67

78
use heapless::{consts::*, String, Vec};
89

910
use self::map::SerializeMap;
1011
use self::seq::SerializeSeq;
11-
use self::struct_::SerializeStruct;
12+
use self::struct_::{SerializeStruct, SerializeStructVariant};
1213

1314
mod map;
1415
mod seq;
@@ -146,7 +147,7 @@ where
146147
type SerializeTupleVariant = Unreachable;
147148
type SerializeMap = SerializeMap<'a, B>;
148149
type SerializeStruct = SerializeStruct<'a, B>;
149-
type SerializeStructVariant = Unreachable;
150+
type SerializeStructVariant = SerializeStructVariant<'a, B>;
150151

151152
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
152153
if v {
@@ -234,11 +235,11 @@ where
234235
}
235236

236237
fn serialize_unit(self) -> Result<Self::Ok> {
237-
unreachable!()
238+
self.serialize_none()
238239
}
239240

240241
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
241-
unreachable!()
242+
self.serialize_unit()
242243
}
243244

244245
fn serialize_unit_variant(
@@ -253,25 +254,29 @@ where
253254
fn serialize_newtype_struct<T: ?Sized>(
254255
self,
255256
_name: &'static str,
256-
_value: &T,
257+
value: &T,
257258
) -> Result<Self::Ok>
258259
where
259260
T: ser::Serialize,
260261
{
261-
unreachable!()
262+
value.serialize(self)
262263
}
263264

264265
fn serialize_newtype_variant<T: ?Sized>(
265-
self,
266+
mut self,
266267
_name: &'static str,
267268
_variant_index: u32,
268-
_variant: &'static str,
269-
_value: &T,
269+
variant: &'static str,
270+
value: &T,
270271
) -> Result<Self::Ok>
271272
where
272273
T: ser::Serialize,
273274
{
274-
unreachable!()
275+
self.buf.push(b'{')?;
276+
let mut s = SerializeStruct::new(&mut self);
277+
s.serialize_field(variant, value)?;
278+
s.end()?;
279+
Ok(())
275280
}
276281

277282
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
@@ -321,7 +326,9 @@ where
321326
_variant: &'static str,
322327
_len: usize,
323328
) -> Result<Self::SerializeStructVariant> {
324-
unreachable!()
329+
self.buf.push(b'{')?;
330+
331+
Ok(SerializeStructVariant::new(self))
325332
}
326333

327334
fn collect_str<T: ?Sized>(self, _value: &T) -> Result<Self::Ok>
@@ -597,4 +604,40 @@ mod tests {
597604
r#"{"a":true,"b":false}"#
598605
);
599606
}
607+
608+
#[test]
609+
fn test_unit() {
610+
let a = ();
611+
assert_eq!(&*crate::to_string::<N, _>(&a).unwrap(), r#"null"#);
612+
}
613+
614+
#[test]
615+
fn test_newtype_struct() {
616+
#[derive(Serialize)]
617+
struct A(pub u32);
618+
let a = A(54);
619+
assert_eq!(&*crate::to_string::<N, _>(&a).unwrap(), r#"54"#);
620+
}
621+
622+
#[test]
623+
fn test_newtype_variant() {
624+
#[derive(Serialize)]
625+
enum A {
626+
A(u32),
627+
}
628+
let a = A::A(54);
629+
630+
assert_eq!(&*crate::to_string::<N, _>(&a).unwrap(), r#"{"A":54}"#);
631+
}
632+
633+
#[test]
634+
fn test_struct_variant() {
635+
#[derive(Serialize)]
636+
enum A {
637+
A { x: u32, y: u16 },
638+
}
639+
let a = A::A { x: 54, y: 720 };
640+
641+
assert_eq!(&*crate::to_string::<N, _>(&a).unwrap(), r#"{"x":54,"y":720}"#);
642+
}
600643
}

src/ser/struct_.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,52 @@ where
5252
Ok(())
5353
}
5454
}
55+
56+
pub struct SerializeStructVariant<'a, B>
57+
where
58+
B: ArrayLength<u8>,
59+
{
60+
ser: &'a mut Serializer<B>,
61+
first: bool,
62+
}
63+
64+
impl<'a, B> SerializeStructVariant<'a, B>
65+
where
66+
B: ArrayLength<u8>,
67+
{
68+
pub(crate) fn new(ser: &'a mut Serializer<B>) -> Self {
69+
SerializeStructVariant { ser, first: true }
70+
}
71+
}
72+
73+
impl<'a, B> ser::SerializeStructVariant for SerializeStructVariant<'a, B>
74+
where
75+
B: ArrayLength<u8>,
76+
{
77+
type Ok = ();
78+
type Error = Error;
79+
80+
fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<()>
81+
where
82+
T: ser::Serialize,
83+
{
84+
// XXX if `value` is `None` we not produce any output for this field
85+
if !self.first {
86+
self.ser.buf.push(b',')?;
87+
}
88+
self.first = false;
89+
90+
self.ser.buf.push(b'"')?;
91+
self.ser.buf.extend_from_slice(key.as_bytes())?;
92+
self.ser.buf.extend_from_slice(b"\":")?;
93+
94+
value.serialize(&mut *self.ser)?;
95+
96+
Ok(())
97+
}
98+
99+
fn end(self) -> Result<Self::Ok> {
100+
self.ser.buf.push(b'}')?;
101+
Ok(())
102+
}
103+
}

0 commit comments

Comments
 (0)