diff --git a/serde_with/src/de/impls.rs b/serde_with/src/de/impls.rs index 6b83ca3b..de00509a 100644 --- a/serde_with/src/de/impls.rs +++ b/serde_with/src/de/impls.rs @@ -908,80 +908,6 @@ where } } -#[cfg(feature = "alloc")] -impl<'de, T, U> DeserializeAs<'de, Vec> for VecSkipError -where - U: DeserializeAs<'de, T>, -{ - fn deserialize_as(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - { - enum GoodOrError { - Good(T), - // Only here to consume the TAs generic - Error(PhantomData), - } - - impl<'de, T, TAs> Deserialize<'de> for GoodOrError - where - TAs: DeserializeAs<'de, T>, - { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let is_hr = deserializer.is_human_readable(); - let content: content::de::Content<'de> = Deserialize::deserialize(deserializer)?; - - Ok( - match >::deserialize( - content::de::ContentDeserializer::::new(content, is_hr), - ) { - Ok(elem) => GoodOrError::Good(elem.into_inner()), - Err(_) => GoodOrError::Error(PhantomData), - }, - ) - } - } - - struct SeqVisitor { - marker: PhantomData, - marker2: PhantomData, - } - - impl<'de, T, TAs> Visitor<'de> for SeqVisitor - where - TAs: DeserializeAs<'de, T>, - { - type Value = Vec; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("a sequence") - } - - fn visit_seq(self, seq: A) -> Result - where - A: SeqAccess<'de>, - { - utils::SeqIter::new(seq) - .filter_map(|res: Result, A::Error>| match res { - Ok(GoodOrError::Good(value)) => Some(Ok(value)), - Ok(GoodOrError::Error(_)) => None, - Err(err) => Some(Err(err)), - }) - .collect() - } - } - - let visitor = SeqVisitor:: { - marker: PhantomData, - marker2: PhantomData, - }; - deserializer.deserialize_seq(visitor) - } -} - impl<'de, Str> DeserializeAs<'de, Option> for NoneAsEmptyString where Str: FromStr, diff --git a/serde_with/src/de/mod.rs b/serde_with/src/de/mod.rs index 984950cb..c566f371 100644 --- a/serde_with/src/de/mod.rs +++ b/serde_with/src/de/mod.rs @@ -10,6 +10,8 @@ #[cfg(feature = "alloc")] mod duplicates; mod impls; +#[cfg(feature = "alloc")] +mod skip_error; use crate::prelude::*; diff --git a/serde_with/src/de/skip_error.rs b/serde_with/src/de/skip_error.rs new file mode 100644 index 00000000..a50d4bd4 --- /dev/null +++ b/serde_with/src/de/skip_error.rs @@ -0,0 +1,75 @@ +use crate::prelude::*; + +enum GoodOrError { + Good(T), + // Only here to consume the TAs generic + Error(PhantomData), +} + +impl<'de, T, TAs> Deserialize<'de> for GoodOrError +where + TAs: DeserializeAs<'de, T>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let is_hr = deserializer.is_human_readable(); + let content: content::de::Content<'de> = Deserialize::deserialize(deserializer)?; + + Ok( + match >::deserialize(content::de::ContentDeserializer::< + D::Error, + >::new(content, is_hr)) + { + Ok(elem) => GoodOrError::Good(elem.into_inner()), + Err(_) => GoodOrError::Error(PhantomData), + }, + ) + } +} + +impl<'de, T, U> DeserializeAs<'de, Vec> for VecSkipError +where + U: DeserializeAs<'de, T>, +{ + fn deserialize_as(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + struct SeqVisitor { + marker: PhantomData, + marker2: PhantomData, + } + + impl<'de, T, TAs> Visitor<'de> for SeqVisitor + where + TAs: DeserializeAs<'de, T>, + { + type Value = Vec; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("a sequence") + } + + fn visit_seq(self, seq: A) -> Result + where + A: SeqAccess<'de>, + { + utils::SeqIter::new(seq) + .filter_map(|res: Result, A::Error>| match res { + Ok(GoodOrError::Good(value)) => Some(Ok(value)), + Ok(GoodOrError::Error(_)) => None, + Err(err) => Some(Err(err)), + }) + .collect() + } + } + + let visitor = SeqVisitor:: { + marker: PhantomData, + marker2: PhantomData, + }; + deserializer.deserialize_seq(visitor) + } +} diff --git a/serde_with/src/ser/impls.rs b/serde_with/src/ser/impls.rs index e42b9139..03ae0b3d 100644 --- a/serde_with/src/ser/impls.rs +++ b/serde_with/src/ser/impls.rs @@ -559,19 +559,6 @@ where } } -#[cfg(feature = "alloc")] -impl SerializeAs> for VecSkipError -where - U: SerializeAs, -{ - fn serialize_as(source: &Vec, serializer: S) -> Result - where - S: Serializer, - { - Vec::::serialize_as(source, serializer) - } -} - impl SerializeAs> for NoneAsEmptyString where T: Display, diff --git a/serde_with/src/ser/mod.rs b/serde_with/src/ser/mod.rs index 8c599d4b..42895b81 100644 --- a/serde_with/src/ser/mod.rs +++ b/serde_with/src/ser/mod.rs @@ -10,6 +10,8 @@ #[cfg(feature = "alloc")] mod duplicates; mod impls; +#[cfg(feature = "alloc")] +mod skip_error; use crate::prelude::*; diff --git a/serde_with/src/ser/skip_error.rs b/serde_with/src/ser/skip_error.rs new file mode 100644 index 00000000..02509cec --- /dev/null +++ b/serde_with/src/ser/skip_error.rs @@ -0,0 +1,13 @@ +use crate::prelude::*; + +impl SerializeAs> for VecSkipError +where + U: SerializeAs, +{ + fn serialize_as(source: &Vec, serializer: S) -> Result + where + S: Serializer, + { + Vec::::serialize_as(source, serializer) + } +}