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