Skip to content

Commit b47f77c

Browse files
authored
Merge pull request #604 from epage/ser
fix(serde): Bubble up nested None errors
2 parents 954b65a + 4711cdb commit b47f77c

File tree

2 files changed

+208
-5
lines changed

2 files changed

+208
-5
lines changed

crates/toml/tests/testsuite/serde.rs

+21
Original file line numberDiff line numberDiff line change
@@ -1094,3 +1094,24 @@ fn datetime_offset_issue_496() {
10941094
let output = toml.to_string();
10951095
snapbox::assert_eq(original, output);
10961096
}
1097+
1098+
#[test]
1099+
fn serialize_array_with_none_value() {
1100+
#[derive(Serialize)]
1101+
struct Document {
1102+
values: Vec<Option<usize>>,
1103+
}
1104+
1105+
let input = Document {
1106+
values: vec![Some(1), Some(2), Some(3)],
1107+
};
1108+
let expected = "values = [1, 2, 3]\n";
1109+
let raw = toml::to_string(&input).unwrap();
1110+
snapbox::assert_eq(expected, raw);
1111+
1112+
let input = Document {
1113+
values: vec![Some(1), None, Some(3)],
1114+
};
1115+
let err = toml::to_string(&input).unwrap_err();
1116+
snapbox::assert_eq("unsupported None value", err.to_string());
1117+
}

crates/toml_edit/src/ser/map.rs

+187-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{Error, KeySerializer};
1+
use super::{Error, KeySerializer, ValueSerializer};
22

33
#[doc(hidden)]
44
pub enum SerializeMap {
@@ -174,7 +174,8 @@ impl serde::ser::SerializeMap for SerializeInlineTable {
174174
where
175175
T: serde::ser::Serialize,
176176
{
177-
let res = value.serialize(super::ValueSerializer {});
177+
let mut value_serializer = MapValueSerializer::new();
178+
let res = value.serialize(&mut value_serializer);
178179
match res {
179180
Ok(item) => {
180181
let key = self.key.take().unwrap();
@@ -185,7 +186,7 @@ impl serde::ser::SerializeMap for SerializeInlineTable {
185186
self.items.insert(key, kv);
186187
}
187188
Err(e) => {
188-
if e != Error::UnsupportedNone {
189+
if !(e == Error::UnsupportedNone && value_serializer.is_none) {
189190
return Err(e);
190191
}
191192
}
@@ -210,7 +211,8 @@ impl serde::ser::SerializeStruct for SerializeInlineTable {
210211
where
211212
T: serde::ser::Serialize,
212213
{
213-
let res = value.serialize(super::ValueSerializer {});
214+
let mut value_serializer = MapValueSerializer::new();
215+
let res = value.serialize(&mut value_serializer);
214216
match res {
215217
Ok(item) => {
216218
let kv = crate::table::TableKeyValue::new(
@@ -220,7 +222,7 @@ impl serde::ser::SerializeStruct for SerializeInlineTable {
220222
self.items.insert(crate::InternalString::from(key), kv);
221223
}
222224
Err(e) => {
223-
if e != Error::UnsupportedNone {
225+
if !(e == Error::UnsupportedNone && value_serializer.is_none) {
224226
return Err(e);
225227
}
226228
}
@@ -403,3 +405,183 @@ impl serde::ser::Serializer for DatetimeFieldSerializer {
403405
Err(Error::DateInvalid)
404406
}
405407
}
408+
409+
#[derive(Default)]
410+
struct MapValueSerializer {
411+
is_none: bool,
412+
}
413+
414+
impl MapValueSerializer {
415+
fn new() -> Self {
416+
Self { is_none: false }
417+
}
418+
}
419+
420+
impl serde::ser::Serializer for &mut MapValueSerializer {
421+
type Ok = crate::Value;
422+
type Error = Error;
423+
type SerializeSeq = super::SerializeValueArray;
424+
type SerializeTuple = super::SerializeValueArray;
425+
type SerializeTupleStruct = super::SerializeValueArray;
426+
type SerializeTupleVariant = super::SerializeValueArray;
427+
type SerializeMap = super::SerializeMap;
428+
type SerializeStruct = super::SerializeMap;
429+
type SerializeStructVariant = serde::ser::Impossible<Self::Ok, Self::Error>;
430+
431+
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
432+
ValueSerializer::new().serialize_bool(v)
433+
}
434+
435+
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
436+
ValueSerializer::new().serialize_i8(v)
437+
}
438+
439+
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
440+
ValueSerializer::new().serialize_i16(v)
441+
}
442+
443+
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
444+
ValueSerializer::new().serialize_i32(v)
445+
}
446+
447+
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
448+
ValueSerializer::new().serialize_i64(v)
449+
}
450+
451+
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
452+
ValueSerializer::new().serialize_u8(v)
453+
}
454+
455+
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
456+
ValueSerializer::new().serialize_u16(v)
457+
}
458+
459+
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
460+
ValueSerializer::new().serialize_u32(v)
461+
}
462+
463+
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
464+
ValueSerializer::new().serialize_u64(v)
465+
}
466+
467+
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
468+
ValueSerializer::new().serialize_f32(v)
469+
}
470+
471+
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
472+
ValueSerializer::new().serialize_f64(v)
473+
}
474+
475+
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
476+
ValueSerializer::new().serialize_char(v)
477+
}
478+
479+
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
480+
ValueSerializer::new().serialize_str(v)
481+
}
482+
483+
fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
484+
ValueSerializer::new().serialize_bytes(value)
485+
}
486+
487+
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
488+
self.is_none = true;
489+
Err(Error::UnsupportedNone)
490+
}
491+
492+
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
493+
where
494+
T: serde::ser::Serialize,
495+
{
496+
ValueSerializer::new().serialize_some(value)
497+
}
498+
499+
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
500+
ValueSerializer::new().serialize_unit()
501+
}
502+
503+
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
504+
ValueSerializer::new().serialize_unit_struct(name)
505+
}
506+
507+
fn serialize_unit_variant(
508+
self,
509+
name: &'static str,
510+
variant_index: u32,
511+
variant: &'static str,
512+
) -> Result<Self::Ok, Self::Error> {
513+
ValueSerializer::new().serialize_unit_variant(name, variant_index, variant)
514+
}
515+
516+
fn serialize_newtype_struct<T: ?Sized>(
517+
self,
518+
name: &'static str,
519+
value: &T,
520+
) -> Result<Self::Ok, Self::Error>
521+
where
522+
T: serde::ser::Serialize,
523+
{
524+
ValueSerializer::new().serialize_newtype_struct(name, value)
525+
}
526+
527+
fn serialize_newtype_variant<T: ?Sized>(
528+
self,
529+
name: &'static str,
530+
variant_index: u32,
531+
variant: &'static str,
532+
value: &T,
533+
) -> Result<Self::Ok, Self::Error>
534+
where
535+
T: serde::ser::Serialize,
536+
{
537+
ValueSerializer::new().serialize_newtype_variant(name, variant_index, variant, value)
538+
}
539+
540+
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
541+
ValueSerializer::new().serialize_seq(len)
542+
}
543+
544+
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
545+
ValueSerializer::new().serialize_tuple(len)
546+
}
547+
548+
fn serialize_tuple_struct(
549+
self,
550+
name: &'static str,
551+
len: usize,
552+
) -> Result<Self::SerializeTupleStruct, Self::Error> {
553+
ValueSerializer::new().serialize_tuple_struct(name, len)
554+
}
555+
556+
fn serialize_tuple_variant(
557+
self,
558+
name: &'static str,
559+
variant_index: u32,
560+
variant: &'static str,
561+
len: usize,
562+
) -> Result<Self::SerializeTupleVariant, Self::Error> {
563+
ValueSerializer::new().serialize_tuple_variant(name, variant_index, variant, len)
564+
}
565+
566+
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
567+
ValueSerializer::new().serialize_map(len)
568+
}
569+
570+
fn serialize_struct(
571+
self,
572+
name: &'static str,
573+
len: usize,
574+
) -> Result<Self::SerializeStruct, Self::Error> {
575+
ValueSerializer::new().serialize_struct(name, len)
576+
}
577+
578+
fn serialize_struct_variant(
579+
self,
580+
name: &'static str,
581+
variant_index: u32,
582+
variant: &'static str,
583+
len: usize,
584+
) -> Result<Self::SerializeStructVariant, Self::Error> {
585+
ValueSerializer::new().serialize_struct_variant(name, variant_index, variant, len)
586+
}
587+
}

0 commit comments

Comments
 (0)