fix: playlist deserialization error, add VecSkipErrorWrap
This commit is contained in:
parent
bb396968dc
commit
963ff14dc1
10 changed files with 129 additions and 55 deletions
|
|
@ -6,7 +6,7 @@ mod vec_log_err;
|
|||
|
||||
pub use date::DateYmd;
|
||||
pub use range::Range;
|
||||
pub use vec_log_err::VecLogError;
|
||||
pub use vec_log_err::{VecLogError, VecSkipErrorWrap};
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::{fmt, marker::PhantomData};
|
||||
|
||||
use serde::{
|
||||
de::{SeqAccess, Visitor},
|
||||
de::{IgnoredAny, SeqAccess, Visitor},
|
||||
Deserialize,
|
||||
};
|
||||
use serde_with::{de::DeserializeAsWrap, DeserializeAs};
|
||||
|
|
@ -89,6 +89,59 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Reimplementation of VecSkipError using a type wrapper
|
||||
/// to allow use with generics
|
||||
pub struct VecSkipErrorWrap<T>(pub Vec<T>);
|
||||
|
||||
impl<'de, T> Deserialize<'de> for VecSkipErrorWrap<T>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum GoodOrError<T> {
|
||||
Good(T),
|
||||
Error(IgnoredAny),
|
||||
}
|
||||
|
||||
struct SeqVisitor<T>(PhantomData<T>);
|
||||
|
||||
impl<'de, T> Visitor<'de> for SeqVisitor<T>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
{
|
||||
type Value = VecSkipErrorWrap<T>;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
formatter.write_str("a sequence")
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
let mut values = Vec::with_capacity(seq.size_hint().unwrap_or_default());
|
||||
|
||||
while let Some(value) = seq.next_element()? {
|
||||
match value {
|
||||
GoodOrError::<T>::Good(value) => {
|
||||
values.push(value);
|
||||
}
|
||||
GoodOrError::<T>::Error(_) => {}
|
||||
}
|
||||
}
|
||||
Ok(VecSkipErrorWrap(values))
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_seq(SeqVisitor(PhantomData::<T>))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde::Deserialize;
|
||||
|
|
|
|||
Reference in a new issue