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