use std::collections::HashMap;
use url::Url;
#[derive(Debug, serde::Deserialize)]
#[serde(tag = "status")]
pub enum GetVideoResponse {
#[serde(rename = "ok")]
Ok(Box<GetVideoResponseOk>),
#[serde(rename = "error")]
Error(GetVideoResponseError),
}
impl GetVideoResponse {
pub fn into_result(self) -> Result<Box<GetVideoResponseOk>, GetVideoResponseError> {
match self {
Self::Ok(ok) => Ok(ok),
Self::Error(err) => Err(err),
}
}
}
#[derive(Debug, serde::Deserialize)]
pub struct GetVideoResponseOk {
pub affected: i32,
pub already_downloaded: bool,
pub file_hash: Box<str>,
pub meme: Box<str>,
pub meme_msg: Box<str>,
pub points: i64,
pub thumbnail_name: Box<str>,
pub share_url: Url,
pub short_id: Box<str>,
pub url: Url,
pub user_email: Box<str>,
pub user_hash: Box<str>,
pub video_data: Option<Box<VideoData>>,
pub video_size: Box<str>,
}
#[derive(Debug, serde::Deserialize)]
pub struct VideoData {
pub author: String,
pub duration: u64,
pub has_audio: bool,
pub is_gif: bool,
pub is_video: bool,
#[serde(rename = "type")]
pub kind: Box<str>,
pub nsfw: bool,
pub provider_name: Option<Box<str>>,
pub subreddit: Box<str>,
pub thumbnail: Url,
pub title: Box<str>,
pub url: Url,
#[serde(flatten)]
pub extra: HashMap<String, serde_json::Value>,
}
#[derive(Debug, serde::Deserialize)]
pub struct GetVideoResponseError {
#[serde(rename = "errores")]
pub errors: Option<HashMap<String, String>>,
pub meme: Option<Box<str>>,
pub msg: Option<Box<str>>,
}
impl std::fmt::Display for GetVideoResponseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match (&self.msg, &self.errors) {
(Some(msg), _) => msg.fmt(f),
(_, Some(errors)) => errors
.values()
.next()
.map(|s| s.as_str())
.unwrap_or("failed to get video response")
.fmt(f),
(None, None) => "failed to get video response".fmt(f),
}
}
}
impl std::error::Error for GetVideoResponseError {}
#[cfg(test)]
mod test {
use super::*;
const VALID_1: &str = include_str!("../../test_data/valid_get_video1.json");
const VALID_2: &str = include_str!("../../test_data/valid_get_video2.json");
const INVALID_CSRF: &str = include_str!("../../test_data/invalid_csrf_get_video.json");
const INVALID_POST_TYPE: &str =
include_str!("../../test_data/invalid_post_type_get_video.json");
#[test]
fn parse_valid_1_get_video_response() {
let res: GetVideoResponse = serde_json::from_str(VALID_1).unwrap();
dbg!(res);
}
#[test]
fn parse_valid_2_get_video_response() {
let res: GetVideoResponse = serde_json::from_str(VALID_2).unwrap();
dbg!(res);
}
#[test]
fn parse_invalid_csrf_get_video_response() {
let res: GetVideoResponse = serde_json::from_str(INVALID_CSRF).unwrap();
dbg!(res);
}
#[test]
fn parse_invalid_post_type_get_video_response() {
let res: GetVideoResponse = serde_json::from_str(INVALID_POST_TYPE).unwrap();
dbg!(res);
}
}