Skip to content

Commit 2a97b87

Browse files
authored
Merge pull request #42 from MathiasKoch/PR25
Newtype, variants and unit
2 parents 51f32e1 + 6830a15 commit 2a97b87

File tree

5 files changed

+224
-48
lines changed

5 files changed

+224
-48
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121

2222
include:
2323
# Test MSRV
24-
- rust: 1.36.0
24+
- rust: 1.40.0
2525
TARGET: x86_64-unknown-linux-gnu
2626

2727
# Test nightly but don't fail

src/de/enum_.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,56 @@ impl<'de, 'a> de::VariantAccess<'de> for UnitVariantAccess<'a, 'de> {
5353
Err(Error::InvalidType)
5454
}
5555
}
56+
57+
pub(crate) struct VariantAccess<'a, 'b> {
58+
de: &'a mut Deserializer<'b>,
59+
}
60+
61+
impl<'a, 'b> VariantAccess<'a, 'b> {
62+
pub(crate) fn new(de: &'a mut Deserializer<'b>) -> Self {
63+
VariantAccess { de }
64+
}
65+
}
66+
67+
impl<'a, 'de> de::EnumAccess<'de> for VariantAccess<'a, 'de> {
68+
type Error = Error;
69+
type Variant = Self;
70+
71+
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self)>
72+
where
73+
V: de::DeserializeSeed<'de>,
74+
{
75+
let variant = seed.deserialize(&mut *self.de)?;
76+
self.de.parse_object_colon()?;
77+
Ok((variant, self))
78+
}
79+
}
80+
81+
impl<'de, 'a> de::VariantAccess<'de> for VariantAccess<'a, 'de> {
82+
type Error = Error;
83+
84+
fn unit_variant(self) -> Result<()> {
85+
de::Deserialize::deserialize(self.de)
86+
}
87+
88+
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
89+
where
90+
T: de::DeserializeSeed<'de>,
91+
{
92+
seed.deserialize(self.de)
93+
}
94+
95+
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
96+
where
97+
V: de::Visitor<'de>,
98+
{
99+
de::Deserializer::deserialize_seq(self.de, visitor)
100+
}
101+
102+
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
103+
where
104+
V: de::Visitor<'de>,
105+
{
106+
de::Deserializer::deserialize_struct(self.de, "", fields, visitor)
107+
}
108+
}

src/de/mod.rs

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use core::{fmt, str};
55

66
use serde::de::{self, Visitor};
77

8-
use self::enum_::UnitVariantAccess;
8+
use self::enum_::{UnitVariantAccess, VariantAccess};
99
use self::map::MapAccess;
1010
use self::seq::SeqAccess;
1111

@@ -18,6 +18,7 @@ pub type Result<T> = core::result::Result<T, Error>;
1818

1919
/// This type represents all possible errors that can occur when deserializing JSON data
2020
#[derive(Debug, PartialEq)]
21+
#[non_exhaustive]
2122
pub enum Error {
2223
/// EOF while parsing a list.
2324
EofWhileParsingList,
@@ -73,9 +74,6 @@ pub enum Error {
7374
/// Error with a custom message that was preserved.
7475
#[cfg(feature = "custom-error-messages")]
7576
CustomErrorWithMessage(heapless::String<heapless::consts::U64>),
76-
77-
#[doc(hidden)]
78-
__Extensible,
7977
}
8078

8179
#[cfg(feature = "std")]
@@ -498,28 +496,40 @@ impl<'a, 'de> de::Deserializer<'de> for &'a mut Deserializer<'de> {
498496
}
499497
}
500498

501-
/// Unsupported. Use a more specific deserialize_* method
502-
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value>
499+
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
503500
where
504501
V: Visitor<'de>,
505502
{
506-
unreachable!()
503+
let peek = match self.parse_whitespace() {
504+
Some(b) => b,
505+
None => {
506+
return Err(Error::EofWhileParsingValue);
507+
}
508+
};
509+
510+
match peek {
511+
b'n' => {
512+
self.eat_char();
513+
self.parse_ident(b"ull")?;
514+
visitor.visit_unit()
515+
}
516+
_ => Err(Error::InvalidType),
517+
}
507518
}
508519

509-
/// Unsupported. Use a more specific deserialize_* method
510-
fn deserialize_unit_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value>
520+
fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
511521
where
512522
V: Visitor<'de>,
513523
{
514-
unreachable!()
524+
self.deserialize_unit(visitor)
515525
}
516526

517527
/// Unsupported. We can’t parse newtypes because we don’t know the underlying type.
518-
fn deserialize_newtype_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value>
528+
fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
519529
where
520530
V: Visitor<'de>,
521531
{
522-
unreachable!()
532+
visitor.visit_newtype_struct(self)
523533
}
524534

525535
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
@@ -600,6 +610,17 @@ impl<'a, 'de> de::Deserializer<'de> for &'a mut Deserializer<'de> {
600610
{
601611
match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
602612
b'"' => visitor.visit_enum(UnitVariantAccess::new(self)),
613+
b'{' => {
614+
self.eat_char();
615+
let value = visitor.visit_enum(VariantAccess::new(self))?;
616+
match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
617+
b'}' => {
618+
self.eat_char();
619+
Ok(value)
620+
}
621+
_ => Err(Error::ExpectedSomeValue),
622+
}
623+
}
603624
_ => Err(Error::ExpectedSomeValue),
604625
}
605626
}
@@ -961,6 +982,41 @@ mod tests {
961982
assert!(crate::from_str::<Temperature>(r#"{ "temperature": -1 }"#).is_err());
962983
}
963984

985+
#[test]
986+
fn test_unit() {
987+
assert_eq!(crate::from_str::<()>(r#"null"#), Ok(((), 4)));
988+
}
989+
990+
#[test]
991+
fn newtype_struct() {
992+
#[derive(Deserialize, Debug, PartialEq)]
993+
struct A(pub u32);
994+
995+
assert_eq!(crate::from_str::<A>(r#"54"#), Ok((A(54), 2)));
996+
}
997+
998+
#[test]
999+
fn test_newtype_variant() {
1000+
#[derive(Deserialize, Debug, PartialEq)]
1001+
enum A {
1002+
A(u32),
1003+
}
1004+
let a = A::A(54);
1005+
let x = crate::from_str::<A>(r#"{"A":54}"#);
1006+
assert_eq!(x, Ok((a, 8)));
1007+
}
1008+
1009+
#[test]
1010+
fn test_struct_variant() {
1011+
#[derive(Deserialize, Debug, PartialEq)]
1012+
enum A {
1013+
A { x: u32, y: u16 },
1014+
}
1015+
let a = A::A { x: 54, y: 720 };
1016+
let x = crate::from_str::<A>(r#"{"A": {"x":54,"y":720 } }"#);
1017+
assert_eq!(x, Ok((a, 25)));
1018+
}
1019+
9641020
#[test]
9651021
#[cfg(not(feature = "custom-error-messages"))]
9661022
fn struct_tuple() {

src/ser/mod.rs

Lines changed: 62 additions & 35 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;
@@ -19,11 +20,10 @@ pub type Result<T> = ::core::result::Result<T, Error>;
1920

2021
/// This type represents all possible errors that can occur when serializing JSON data
2122
#[derive(Debug)]
23+
#[non_exhaustive]
2224
pub enum Error {
2325
/// Buffer is full
2426
BufferFull,
25-
#[doc(hidden)]
26-
__Extensible,
2727
}
2828

2929
impl From<()> for Error {
@@ -84,7 +84,7 @@ impl<'a> Serializer<'a> {
8484
Err(Error::BufferFull)
8585
} else {
8686
for c in other {
87-
unsafe { self.push_unchecked(c.clone()) };
87+
unsafe { self.push_unchecked(*c) };
8888
}
8989
Ok(())
9090
}
@@ -178,7 +178,7 @@ impl<'a, 'b: 'a> ser::Serializer for &'a mut Serializer<'b> {
178178
type SerializeTupleVariant = Unreachable;
179179
type SerializeMap = SerializeMap<'a, 'b>;
180180
type SerializeStruct = SerializeStruct<'a, 'b>;
181-
type SerializeStructVariant = Unreachable;
181+
type SerializeStructVariant = SerializeStructVariant<'a, 'b>;
182182

183183
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
184184
if v {
@@ -320,11 +320,11 @@ impl<'a, 'b: 'a> ser::Serializer for &'a mut Serializer<'b> {
320320
}
321321

322322
fn serialize_unit(self) -> Result<Self::Ok> {
323-
unreachable!()
323+
self.serialize_none()
324324
}
325325

326326
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
327-
unreachable!()
327+
self.serialize_unit()
328328
}
329329

330330
fn serialize_unit_variant(
@@ -336,28 +336,28 @@ impl<'a, 'b: 'a> ser::Serializer for &'a mut Serializer<'b> {
336336
self.serialize_str(variant)
337337
}
338338

339-
fn serialize_newtype_struct<T: ?Sized>(
340-
self,
341-
_name: &'static str,
342-
_value: &T,
343-
) -> Result<Self::Ok>
339+
fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<Self::Ok>
344340
where
345341
T: ser::Serialize,
346342
{
347-
unreachable!()
343+
value.serialize(self)
348344
}
349345

350346
fn serialize_newtype_variant<T: ?Sized>(
351-
self,
347+
mut self,
352348
_name: &'static str,
353349
_variant_index: u32,
354-
_variant: &'static str,
355-
_value: &T,
350+
variant: &'static str,
351+
value: &T,
356352
) -> Result<Self::Ok>
357353
where
358354
T: ser::Serialize,
359355
{
360-
unreachable!()
356+
self.push(b'{')?;
357+
let mut s = SerializeStruct::new(&mut self);
358+
s.serialize_field(variant, value)?;
359+
s.end()?;
360+
Ok(())
361361
}
362362

363363
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
@@ -404,10 +404,14 @@ impl<'a, 'b: 'a> ser::Serializer for &'a mut Serializer<'b> {
404404
self,
405405
_name: &'static str,
406406
_variant_index: u32,
407-
_variant: &'static str,
407+
variant: &'static str,
408408
_len: usize,
409409
) -> Result<Self::SerializeStructVariant> {
410-
unreachable!()
410+
self.extend_from_slice(b"{\"")?;
411+
self.extend_from_slice(variant.as_bytes())?;
412+
self.extend_from_slice(b"\":{")?;
413+
414+
Ok(SerializeStructVariant::new(self))
411415
}
412416

413417
fn collect_str<T: ?Sized>(self, _value: &T) -> Result<Self::Ok>
@@ -510,22 +514,6 @@ impl ser::SerializeMap for Unreachable {
510514
}
511515
}
512516

513-
impl ser::SerializeStructVariant for Unreachable {
514-
type Ok = ();
515-
type Error = Error;
516-
517-
fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, _value: &T) -> Result<()>
518-
where
519-
T: ser::Serialize,
520-
{
521-
unreachable!()
522-
}
523-
524-
fn end(self) -> Result<Self::Ok> {
525-
unreachable!()
526-
}
527-
}
528-
529517
#[cfg(test)]
530518
mod tests {
531519
use serde_derive::Serialize;
@@ -768,4 +756,43 @@ mod tests {
768756
r#"{"a":true,"b":false}"#
769757
);
770758
}
759+
760+
#[test]
761+
fn test_unit() {
762+
let a = ();
763+
assert_eq!(&*crate::to_string::<N, _>(&a).unwrap(), r#"null"#);
764+
}
765+
766+
#[test]
767+
fn test_newtype_struct() {
768+
#[derive(Serialize)]
769+
struct A(pub u32);
770+
let a = A(54);
771+
assert_eq!(&*crate::to_string::<N, _>(&a).unwrap(), r#"54"#);
772+
}
773+
774+
#[test]
775+
fn test_newtype_variant() {
776+
#[derive(Serialize)]
777+
enum A {
778+
A(u32),
779+
}
780+
let a = A::A(54);
781+
782+
assert_eq!(&*crate::to_string::<N, _>(&a).unwrap(), r#"{"A":54}"#);
783+
}
784+
785+
#[test]
786+
fn test_struct_variant() {
787+
#[derive(Serialize)]
788+
enum A {
789+
A { x: u32, y: u16 },
790+
}
791+
let a = A::A { x: 54, y: 720 };
792+
793+
assert_eq!(
794+
&*crate::to_string::<N, _>(&a).unwrap(),
795+
r#"{"A":{"x":54,"y":720}}"#
796+
);
797+
}
771798
}

0 commit comments

Comments
 (0)