reddit_tube/types/
get_video_response.rs1use std::collections::HashMap;
2use url::Url;
3
4#[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 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#[derive(Debug, serde::Deserialize)]
27pub struct GetVideoResponseOk {
28 pub affected: i32,
30
31 pub already_downloaded: bool,
33
34 pub file_hash: Box<str>,
36
37 pub meme: Box<str>,
39 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 pub video_data: Option<Box<VideoData>>,
51
52 pub video_size: Box<str>,
56}
57
58#[derive(Debug, serde::Deserialize)]
60pub struct VideoData {
61 pub author: String,
63 pub duration: u64,
65 pub has_audio: bool,
67 pub is_gif: bool,
69 pub is_video: bool,
71
72 #[serde(rename = "type")]
74 pub kind: Box<str>,
75
76 pub nsfw: bool,
78 pub provider_name: Option<Box<str>>,
80 pub subreddit: Box<str>,
82 pub thumbnail: Url,
84 pub title: Box<str>,
86 pub url: Url,
88
89 #[serde(flatten)]
91 pub extra: HashMap<String, serde_json::Value>,
92}
93
94#[derive(Debug, serde::Deserialize)]
96pub struct GetVideoResponseError {
97 #[serde(rename = "errores")]
99 pub errors: Option<HashMap<String, String>>,
100 pub meme: Option<Box<str>>,
102 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}