feat: add video details response model
- add paginator, impl for playlist items - small model refactor - add ignore_any deserializer - removed unnecessary clones in response mapping
This commit is contained in:
parent
17b6844eb0
commit
972288d810
32 changed files with 61791 additions and 5316 deletions
|
|
@ -8,6 +8,8 @@ pub use vec_log_err::VecLogError;
|
|||
|
||||
use std::fmt::Debug;
|
||||
|
||||
use serde::{de::IgnoredAny, Deserializer};
|
||||
|
||||
/// This represents a result from a deserializing/mapping operation.
|
||||
/// It holds the desired content (`c`) and a list of warning messages,
|
||||
/// if there occurred minor error during the deserializing or mapping
|
||||
|
|
@ -38,3 +40,59 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserialization method that consumes anything and returns an empty value.
|
||||
/// Intended to be used for a wildcard enum option.
|
||||
///
|
||||
/// Example:
|
||||
/// ```rs
|
||||
/// #[derive(Deserialize)]
|
||||
/// enum Fruit {
|
||||
/// Apple {
|
||||
/// red: bool,
|
||||
/// },
|
||||
/// Banana {
|
||||
/// yellow: bool,
|
||||
/// },
|
||||
/// #[serde(other, deserialize_with = "deserialize_blackhole")]
|
||||
/// None,
|
||||
/// }
|
||||
/// ```
|
||||
pub fn ignore_any<'de, D>(deserializer: D) -> Result<(), D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_ignored_any(IgnoredAny).and(Ok(()))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq)]
|
||||
enum E {
|
||||
Apple {
|
||||
red: bool,
|
||||
},
|
||||
Banana {
|
||||
yellow: bool,
|
||||
},
|
||||
#[serde(other, deserialize_with = "ignore_any")]
|
||||
None,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn t_ignore_any() {
|
||||
assert_eq!(
|
||||
serde_json::from_str::<E>(r#"{"Apple": {"red": true}}"#).unwrap(),
|
||||
E::Apple { red: true }
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::from_str::<E>(r#"{"Lemon": {"yellow": true}}"#).unwrap(),
|
||||
E::None
|
||||
);
|
||||
assert!(serde_json::from_str::<E>(r#"{"Apple": {"yellow": true}}"#).is_err());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,19 @@ impl<'de> DeserializeAs<'de, String> for Text {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'de> DeserializeAs<'de, Vec<String>> for Text {
|
||||
fn deserialize_as<D>(deserializer: D) -> Result<Vec<String>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let text = Text::deserialize(deserializer)?;
|
||||
match text {
|
||||
Text::Simple { text } => Ok(vec![text]),
|
||||
Text::Multiple { runs } => Ok(runs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum TextLink {
|
||||
Video {
|
||||
|
|
@ -227,6 +240,26 @@ impl<'de> DeserializeAs<'de, Vec<TextLink>> for TextLinks {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct AccessibilityText {
|
||||
accessibility: AccessibilityData,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct AccessibilityData {
|
||||
label: String,
|
||||
}
|
||||
|
||||
impl<'de> DeserializeAs<'de, String> for AccessibilityText {
|
||||
fn deserialize_as<D>(deserializer: D) -> Result<String, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let text = AccessibilityText::deserialize(deserializer)?;
|
||||
Ok(text.accessibility.label)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::TextLink;
|
||||
|
|
@ -241,7 +274,7 @@ mod tests {
|
|||
"text": "Hello World"
|
||||
}
|
||||
}"#,
|
||||
"Hello World"
|
||||
vec!["Hello World"]
|
||||
)]
|
||||
#[case(
|
||||
r#"{
|
||||
|
|
@ -249,7 +282,7 @@ mod tests {
|
|||
"simpleText": "Hello World"
|
||||
}
|
||||
}"#,
|
||||
"Hello World"
|
||||
vec!["Hello World"]
|
||||
)]
|
||||
#[case(
|
||||
r#"{
|
||||
|
|
@ -267,9 +300,9 @@ mod tests {
|
|||
]
|
||||
}
|
||||
}"#,
|
||||
"Abo für MBCkpop beenden?"
|
||||
vec!["Abo für ", "MBCkpop", " beenden?"]
|
||||
)]
|
||||
fn t_deserialize_text(#[case] test_json: &str, #[case] exp: &str) {
|
||||
fn t_deserialize_text(#[case] test_json: &str, #[case] exp: Vec<&str>) {
|
||||
#[serde_as]
|
||||
#[derive(Deserialize)]
|
||||
struct S {
|
||||
|
|
@ -277,8 +310,18 @@ mod tests {
|
|||
txt: String,
|
||||
}
|
||||
|
||||
let res = serde_json::from_str::<S>(&test_json).unwrap();
|
||||
assert_eq!(res.txt, exp)
|
||||
#[serde_as]
|
||||
#[derive(Deserialize)]
|
||||
struct SVec {
|
||||
#[serde_as(as = "crate::serializer::text::Text")]
|
||||
txt: Vec<String>,
|
||||
}
|
||||
|
||||
let res_str = serde_json::from_str::<S>(&test_json).unwrap();
|
||||
let res_vec = serde_json::from_str::<SVec>(&test_json).unwrap();
|
||||
|
||||
assert_eq!(res_str.txt, exp.join(""));
|
||||
assert_eq!(res_vec.txt, exp);
|
||||
}
|
||||
|
||||
#[serde_as]
|
||||
|
|
|
|||
Reference in a new issue