我正在尝试将来自端点的 YouTube 数据反序列化http://www.youtube.com/feeds/videos.xml?channel_id=UCHnyfMqiRRG1u-2MsSQLbXA
到Feed
以下程序中的结构中。尽管原始 XML 包含信息,但它仍为结构中的字段Rust
返回 None 。media_group
Entry
注意:粘贴http://www.youtube.com/feeds/videos.xml?channel_id=UCHnyfMqiRRG1u-2MsSQLbXA
到浏览器中以更好地显示 XML
// youtube_data.rs
use hyper::{Body, Client, Uri};
use hyper_tls::HttpsConnector;
use serde::Deserialize;
use quick_xml::de::{from_str, DeError};
use crate::internals::singularity::WidgetError;
impl From<DeError> for WidgetError {
fn from(err: DeError) -> Self {
WidgetError::XmlParse(err.to_string())
}
}
#[derive(Debug, Deserialize)]
#[serde(rename = "feed")]
pub struct Feed {
id: String,
#[serde(rename = "channelId", default)]
yt_channel_id: Option<String>,
title: String,
published: String,
#[serde(default)]
#[serde(rename = "entry")]
entries: Vec<Entry>,
}
#[derive(Debug, Deserialize)]
struct Entry {
id: String,
title: String,
published: String,
#[serde(rename = "mediaGroup")]
media_group: Option<MediaGroup>,
}
#[derive(Debug, Deserialize)]
struct MediaGroup {
#[serde(rename = "mediaTitle")]
title: Option<String>,
#[serde(rename = "mediaContent")]
content: Option<MediaContent>,
#[serde(rename = "mediaThumbnail")]
thumbnail: Option<MediaThumbnail>,
#[serde(rename = "mediaCommunity")]
community: Option<MediaCommunity>,
}
#[derive(Debug, Deserialize)]
struct MediaContent {
#[serde(rename = "@url")]
url: String,
#[serde(rename = "@width")]
width: u32,
#[serde(rename = "@height")]
height: u32,
}
#[derive(Debug, Deserialize)]
struct MediaThumbnail {
#[serde(rename = "@url")]
url: String,
#[serde(rename = "@width")]
width: u32,
#[serde(rename = "@height")]
height: u32,
}
#[derive(Debug, Deserialize)]
struct MediaCommunity {
#[serde(rename = "mediaStarRating")]
star_rating: Option<StarRating>,
#[serde(rename = "mediaStatistics")]
statistics: Option<Statistics>,
}
#[derive(Debug, Deserialize)]
struct StarRating {
#[serde(rename = "@count")]
count: u64,
}
#[derive(Debug, Deserialize)]
struct Statistics {
#[serde(rename = "@views")]
views: u64,
}
pub async fn get_youtube_vids_for_a_channel(channel_id: String) -> Result<Feed, WidgetError> {
let url = format!(
"https://www.youtube.com/feeds/videos.xml?channel_id={}",
channel_id
);
let uri: Uri = url.parse().unwrap();
let https = HttpsConnector::new();
let client = Client::builder().build::<_, Body>(https);
let res = client.get(uri).await?;
let body = hyper::body::to_bytes(res.into_body()).await?;
let response_text = String::from_utf8(body.to_vec())
.map_err(|e| WidgetError::Utf8Error(e.to_string()))?;
// println!("{:#?}", response_text);
let feed: Feed = from_str(&response_text)?;
Ok(feed)
}
// singularity.rs
#[derive(Debug, Error)]
pub enum WidgetError {
#[error("Hyper error: {0}")]
Hyper(#[from] hyper::Error),
#[error("No geocoding data found")]
NoGeocodingData,
#[error("Error in reading HTML file")]
NoHtmlToString,
#[error("Serde JSON error: {0}")]
SerdeJson(#[from] serde_json::Error),
#[error("No timezone found")]
NoTimeZone,
#[error("XML parsing error: {0}")]
XmlParse(String),
#[error("UTF-8 conversion error: {0}")]
Utf8Error(String),
}
使用的依赖项是
[dependencies]
hyper = { version = "0.14", features = ["full"] }
hyper-tls = "0.5"
regex = "1.10.5"
serde = { version = "1.0", features = ["derive"] }
thiserror = "1.0.63"
quick-xml = { version = "0.37", features = ["serialize"] }
即使原始 XML 包含数据,为什么它不能正确地序列化它?