yt_feed_xml/
user.rs

1use color_eyre::eyre::Context;
2use serde::{Deserialize, Serialize};
3
4use crate::{video::Video, xml_feed::Feed};
5
6#[derive(Serialize, Deserialize, Debug, Clone, derive_builder::Builder)]
7pub struct User {
8    pub id: String,
9    pub title: String,
10    pub author: String,
11    pub url: String,
12    pub published: chrono::DateTime<chrono::Utc>,
13    pub videos: Option<Vec<Video>>,
14}
15
16impl User {
17    pub async fn new(user_name: &str) -> Self {
18        let uri = format!(
19            "https://www.youtube.com/feeds/videos.xml?user={}",
20            &user_name
21        );
22
23        let feed: Feed = Feed::new(&uri)
24            .await
25            .wrap_err("Failed to create User.")
26            .unwrap();
27        feed.into()
28    }
29}
30
31impl From<Feed> for User {
32    fn from(f: Feed) -> Self {
33        Self {
34            id: f.channel_id,
35            title: f.title,
36            author: f.author,
37            url: f.url,
38            published: f.published,
39            videos: f.videos,
40        }
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    #[tokio::test]
49    async fn test_cgpgrey_user() {
50        let cgpgrey_user = User::new("cgpgrey").await;
51        assert_eq!(cgpgrey_user.id, "UC2C_jShtL725hvbm1arSV9w");
52        assert_eq!(cgpgrey_user.title, "CGP Grey");
53    }
54
55    #[tokio::test]
56    #[should_panic]
57    async fn test_cgpgrey_user_missing_playlist() {
58        let cgpgrey_user = Feed::new("https://www.youtube.com/feeds/videos.xml?user=cgpgrey")
59            .await
60            .unwrap();
61        let _panic = cgpgrey_user.playlist_id.unwrap();
62    }
63}