twapi_v2/api/
get_2_media_upload.rs

1use crate::responses::{errors::Errors, includes::Includes, media_upload::MediaUpload};
2use crate::{
3    api::{apply_options, execute_twitter, make_url, Authentication, TwapiOptions},
4    error::Error,
5    headers::Headers,
6};
7use reqwest::RequestBuilder;
8use serde::{Deserialize, Serialize};
9
10const URL: &str = "/2/media/upload";
11
12#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Clone)]
13pub enum Command {
14    #[serde(rename = "STATUS")]
15    Status,
16}
17
18impl std::fmt::Display for Command {
19    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
20        match self {
21            Self::Status => write!(f, "STATUS"),
22        }
23    }
24}
25
26impl Default for Command {
27    fn default() -> Self {
28        Self::Status
29    }
30}
31
32#[derive(Debug, Clone, Default)]
33pub struct Api {
34    media_id: String,
35    command: Command,
36    twapi_options: Option<TwapiOptions>,
37}
38
39impl Api {
40    pub fn new(media_id: &str, command: Command) -> Self {
41        Self {
42            media_id: media_id.to_owned(),
43            command,
44            ..Default::default()
45        }
46    }
47
48    pub fn twapi_options(mut self, value: TwapiOptions) -> Self {
49        self.twapi_options = Some(value);
50        self
51    }
52
53    pub fn build(self, authentication: &impl Authentication) -> RequestBuilder {
54        let query_parameters = vec![
55            ("media_id", self.media_id),
56            ("command", self.command.to_string()),
57        ];
58        let client = reqwest::Client::new();
59        let url = make_url(&self.twapi_options, URL);
60        let builder = client.get(&url).query(&query_parameters);
61        authentication.execute(
62            apply_options(builder, &self.twapi_options),
63            "GET",
64            &url,
65            &query_parameters
66                .iter()
67                .map(|it| (it.0, it.1.as_str()))
68                .collect::<Vec<_>>(),
69        )
70    }
71
72    pub async fn execute(
73        self,
74        authentication: &impl Authentication,
75    ) -> Result<(Response, Headers), Error> {
76        execute_twitter(self.build(authentication)).await
77    }
78}
79
80#[derive(Serialize, Deserialize, Debug, Clone, Default)]
81pub struct Response {
82    #[serde(skip_serializing_if = "Option::is_none")]
83    pub data: Option<MediaUpload>,
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub errors: Option<Vec<Errors>>,
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub includes: Option<Includes>,
88    #[serde(flatten)]
89    pub extra: std::collections::HashMap<String, serde_json::Value>,
90}
91
92impl Response {
93    pub fn is_empty_extra(&self) -> bool {
94        let res = self.extra.is_empty()
95            && self
96                .data
97                .as_ref()
98                .map(|it| it.is_empty_extra())
99                .unwrap_or(true)
100            && self
101                .errors
102                .as_ref()
103                .map(|it| it.iter().all(|item| item.is_empty_extra()))
104                .unwrap_or(true)
105            && self
106                .includes
107                .as_ref()
108                .map(|it| it.is_empty_extra())
109                .unwrap_or(true);
110        if !res {
111            println!("Response {:?}", self.extra);
112        }
113        res
114    }
115}