fix: playlist deserialization error, add VecSkipErrorWrap

This commit is contained in:
ThetaDev 2023-05-05 17:13:03 +02:00
parent bb396968dc
commit 963ff14dc1
10 changed files with 129 additions and 55 deletions

View file

@ -47,12 +47,17 @@ pub(crate) mod channel_rss;
#[cfg(feature = "rss")]
pub(crate) use channel_rss::ChannelRss;
use serde::Deserialize;
use std::borrow::Cow;
use std::marker::PhantomData;
use serde::{
de::{IgnoredAny, Visitor},
Deserialize,
};
use serde_with::{json::JsonString, serde_as, VecSkipError};
use crate::error::ExtractionError;
use crate::serializer::MapResult;
use crate::serializer::{text::Text, VecLogError};
use crate::serializer::{text::Text, MapResult, VecLogError, VecSkipErrorWrap};
use self::video_item::YouTubeListRenderer;
@ -62,10 +67,8 @@ pub(crate) struct ContentRenderer<T> {
pub content: T,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
#[derive(Debug)]
pub(crate) struct ContentsRenderer<T> {
#[serde(alias = "tabs")]
pub contents: Vec<T>,
}
@ -81,6 +84,12 @@ pub(crate) struct SectionList<T> {
pub section_list_renderer: ContentsRenderer<T>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct TwoColumnBrowseResults<T> {
pub two_column_browse_results_renderer: ContentsRenderer<T>,
}
#[derive(Default, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct ThumbnailsWrap {
@ -248,9 +257,52 @@ pub(crate) struct ErrorResponseContent {
pub message: String,
}
/*
#MAPPING
*/
// DESERIALIZER
impl<'de, T> Deserialize<'de> for ContentsRenderer<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct ItemVisitor<T>(PhantomData<T>);
impl<'de, T> Visitor<'de> for ItemVisitor<T>
where
T: Deserialize<'de>,
{
type Value = ContentsRenderer<T>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("map")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let mut contents = None;
while let Some(k) = map.next_key::<Cow<'de, str>>()? {
if k == "contents" || k == "tabs" {
let x = map.next_value::<VecSkipErrorWrap<T>>()?;
contents = Some(ContentsRenderer { contents: x.0 });
} else {
map.next_value::<IgnoredAny>()?;
}
}
contents.ok_or(serde::de::Error::missing_field("contents"))
}
}
deserializer.deserialize_map(ItemVisitor(PhantomData::<T>))
}
}
// MAPPING
impl From<Thumbnail> for crate::model::Thumbnail {
fn from(tn: Thumbnail) -> Self {