Skip to content

Commit

Permalink
Move VecSkipError to a separate file, preparing for MapSkipError
Browse files Browse the repository at this point in the history
  • Loading branch information
johnmave126 authored and jonasbb committed Jul 12, 2024
1 parent 31e9172 commit bf6724d
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 87 deletions.
74 changes: 0 additions & 74 deletions serde_with/src/de/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -908,80 +908,6 @@ where
}
}

#[cfg(feature = "alloc")]
impl<'de, T, U> DeserializeAs<'de, Vec<T>> for VecSkipError<U>
where
U: DeserializeAs<'de, T>,
{
fn deserialize_as<D>(deserializer: D) -> Result<Vec<T>, D::Error>
where
D: Deserializer<'de>,
{
enum GoodOrError<T, TAs> {
Good(T),
// Only here to consume the TAs generic
Error(PhantomData<TAs>),
}

impl<'de, T, TAs> Deserialize<'de> for GoodOrError<T, TAs>
where
TAs: DeserializeAs<'de, T>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let is_hr = deserializer.is_human_readable();
let content: content::de::Content<'de> = Deserialize::deserialize(deserializer)?;

Ok(
match <DeserializeAsWrap<T, TAs>>::deserialize(
content::de::ContentDeserializer::<D::Error>::new(content, is_hr),
) {
Ok(elem) => GoodOrError::Good(elem.into_inner()),
Err(_) => GoodOrError::Error(PhantomData),
},
)
}
}

struct SeqVisitor<T, U> {
marker: PhantomData<T>,
marker2: PhantomData<U>,
}

impl<'de, T, TAs> Visitor<'de> for SeqVisitor<T, TAs>
where
TAs: DeserializeAs<'de, T>,
{
type Value = Vec<T>;

fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a sequence")
}

fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
utils::SeqIter::new(seq)
.filter_map(|res: Result<GoodOrError<T, TAs>, A::Error>| match res {
Ok(GoodOrError::Good(value)) => Some(Ok(value)),
Ok(GoodOrError::Error(_)) => None,
Err(err) => Some(Err(err)),
})
.collect()
}
}

let visitor = SeqVisitor::<T, U> {
marker: PhantomData,
marker2: PhantomData,
};
deserializer.deserialize_seq(visitor)
}
}

impl<'de, Str> DeserializeAs<'de, Option<Str>> for NoneAsEmptyString
where
Str: FromStr,
Expand Down
2 changes: 2 additions & 0 deletions serde_with/src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#[cfg(feature = "alloc")]
mod duplicates;
mod impls;
#[cfg(feature = "alloc")]
mod skip_error;

use crate::prelude::*;

Expand Down
75 changes: 75 additions & 0 deletions serde_with/src/de/skip_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use crate::prelude::*;

enum GoodOrError<T, TAs> {
Good(T),
// Only here to consume the TAs generic
Error(PhantomData<TAs>),
}

impl<'de, T, TAs> Deserialize<'de> for GoodOrError<T, TAs>
where
TAs: DeserializeAs<'de, T>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let is_hr = deserializer.is_human_readable();
let content: content::de::Content<'de> = Deserialize::deserialize(deserializer)?;

Ok(
match <DeserializeAsWrap<T, TAs>>::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<T>> for VecSkipError<U>
where
U: DeserializeAs<'de, T>,
{
fn deserialize_as<D>(deserializer: D) -> Result<Vec<T>, D::Error>
where
D: Deserializer<'de>,
{
struct SeqVisitor<T, U> {
marker: PhantomData<T>,
marker2: PhantomData<U>,
}

impl<'de, T, TAs> Visitor<'de> for SeqVisitor<T, TAs>
where
TAs: DeserializeAs<'de, T>,
{
type Value = Vec<T>;

fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a sequence")
}

fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
utils::SeqIter::new(seq)
.filter_map(|res: Result<GoodOrError<T, TAs>, A::Error>| match res {
Ok(GoodOrError::Good(value)) => Some(Ok(value)),
Ok(GoodOrError::Error(_)) => None,
Err(err) => Some(Err(err)),
})
.collect()
}
}

let visitor = SeqVisitor::<T, U> {
marker: PhantomData,
marker2: PhantomData,
};
deserializer.deserialize_seq(visitor)
}
}
13 changes: 0 additions & 13 deletions serde_with/src/ser/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,19 +559,6 @@ where
}
}

#[cfg(feature = "alloc")]
impl<T, U> SerializeAs<Vec<T>> for VecSkipError<U>
where
U: SerializeAs<T>,
{
fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
Vec::<U>::serialize_as(source, serializer)
}
}

impl<T> SerializeAs<Option<T>> for NoneAsEmptyString
where
T: Display,
Expand Down
2 changes: 2 additions & 0 deletions serde_with/src/ser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#[cfg(feature = "alloc")]
mod duplicates;
mod impls;
#[cfg(feature = "alloc")]
mod skip_error;

use crate::prelude::*;

Expand Down
13 changes: 13 additions & 0 deletions serde_with/src/ser/skip_error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use crate::prelude::*;

impl<T, U> SerializeAs<Vec<T>> for VecSkipError<U>
where
U: SerializeAs<T>,
{
fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
Vec::<U>::serialize_as(source, serializer)
}
}

0 comments on commit bf6724d

Please sign in to comment.