reddit_tube/types/
get_video_response.rs

1use std::collections::HashMap;
2use url::Url;
3
4/// The response for getting a video
5#[derive(Debug, serde::Deserialize)]
6#[serde(tag = "status")]
7pub enum GetVideoResponse {
8    #[serde(rename = "ok")]
9    Ok(Box<GetVideoResponseOk>),
10
11    #[serde(rename = "error")]
12    Error(GetVideoResponseError),
13}
14
15impl GetVideoResponse {
16    /// Transform this into a result
17    pub fn into_result(self) -> Result<Box<GetVideoResponseOk>, GetVideoResponseError> {
18        match self {
19            Self::Ok(ok) => Ok(ok),
20            Self::Error(err) => Err(err),
21        }
22    }
23}
24
25/// A good video response
26#[derive(Debug, serde::Deserialize)]
27pub struct GetVideoResponseOk {
28    /// ?
29    pub affected: i32,
30
31    /// ?
32    pub already_downloaded: bool,
33
34    /// The file hash?
35    pub file_hash: Box<str>,
36
37    /// ?
38    pub meme: Box<str>,
39    /// ?
40    pub meme_msg: Box<str>,
41    pub points: i64,
42    pub thumbnail_name: Box<str>,
43    pub share_url: Url,
44    pub short_id: Box<str>,
45    pub url: Url,
46    pub user_email: Box<str>,
47    pub user_hash: Box<str>,
48
49    /// The video data, if it exists.
50    pub video_data: Option<Box<VideoData>>,
51
52    /// The size of the video as a human-readable string
53    ///
54    /// Example: 614.25KB
55    pub video_size: Box<str>,
56}
57
58/// Video Data
59#[derive(Debug, serde::Deserialize)]
60pub struct VideoData {
61    /// Author
62    pub author: String,
63    /// Video duration
64    pub duration: u64,
65    /// Whether the post has audio
66    pub has_audio: bool,
67    /// Whether the post is a gif
68    pub is_gif: bool,
69    /// Whether the post is a video
70    pub is_video: bool,
71
72    /// The post type?
73    #[serde(rename = "type")]
74    pub kind: Box<str>,
75
76    /// Whether the post is nsfw
77    pub nsfw: bool,
78    /// ?
79    pub provider_name: Option<Box<str>>,
80    /// The subreddit
81    pub subreddit: Box<str>,
82    /// The thumbnail url
83    pub thumbnail: Url,
84    /// The post title
85    pub title: Box<str>,
86    /// The post url?
87    pub url: Url,
88
89    /// Unknown data
90    #[serde(flatten)]
91    pub extra: HashMap<String, serde_json::Value>,
92}
93
94/// Error video response
95#[derive(Debug, serde::Deserialize)]
96pub struct GetVideoResponseError {
97    /// Errors
98    #[serde(rename = "errores")]
99    pub errors: Option<HashMap<String, String>>,
100    /// Meme
101    pub meme: Option<Box<str>>,
102    /// Error message
103    pub msg: Option<Box<str>>,
104}
105
106impl std::fmt::Display for GetVideoResponseError {
107    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108        match (&self.msg, &self.errors) {
109            (Some(msg), _) => msg.fmt(f),
110            (_, Some(errors)) => errors
111                .values()
112                .next()
113                .map(|s| s.as_str())
114                .unwrap_or("failed to get video response")
115                .fmt(f),
116            (None, None) => "failed to get video response".fmt(f),
117        }
118    }
119}
120
121impl std::error::Error for GetVideoResponseError {}
122
123#[cfg(test)]
124mod test {
125    use super::*;
126
127    const VALID_1: &str = include_str!("../../test_data/valid_get_video1.json");
128    const VALID_2: &str = include_str!("../../test_data/valid_get_video2.json");
129    const INVALID_CSRF: &str = include_str!("../../test_data/invalid_csrf_get_video.json");
130    const INVALID_POST_TYPE: &str =
131        include_str!("../../test_data/invalid_post_type_get_video.json");
132
133    #[test]
134    fn parse_valid_1_get_video_response() {
135        let res: GetVideoResponse = serde_json::from_str(VALID_1).unwrap();
136        dbg!(res);
137    }
138
139    #[test]
140    fn parse_valid_2_get_video_response() {
141        let res: GetVideoResponse = serde_json::from_str(VALID_2).unwrap();
142        dbg!(res);
143    }
144
145    #[test]
146    fn parse_invalid_csrf_get_video_response() {
147        let res: GetVideoResponse = serde_json::from_str(INVALID_CSRF).unwrap();
148        dbg!(res);
149    }
150
151    #[test]
152    fn parse_invalid_post_type_get_video_response() {
153        let res: GetVideoResponse = serde_json::from_str(INVALID_POST_TYPE).unwrap();
154        dbg!(res);
155    }
156}