twapi_v2/api/
post_2_media_upload_finalize.rs1use crate::responses::errors::Errors;
2use crate::responses::media_upload::MediaUpload;
3use crate::{
4 api::{apply_options, execute_twitter, make_url, Authentication, TwapiOptions},
5 error::Error,
6 headers::Headers,
7};
8use reqwest::multipart::Form;
9use reqwest::RequestBuilder;
10use serde::{Deserialize, Serialize};
11
12const URL: &str = "/2/media/upload";
13
14#[derive(Debug, Clone, Default)]
15pub struct FormData {
16 pub media_id: String,
17}
18
19impl FormData {
20 fn make_form(self) -> Form {
21 Form::new()
22 .text("command", "FINALIZE")
23 .text("media_id", self.media_id)
24 }
25}
26
27#[derive(Debug, Clone, Default)]
28pub struct Api {
29 form: FormData,
30 twapi_options: Option<TwapiOptions>,
31}
32
33impl Api {
34 pub fn new(form: FormData) -> Self {
35 Self {
36 form,
37 ..Default::default()
38 }
39 }
40
41 pub fn twapi_options(mut self, value: TwapiOptions) -> Self {
42 self.twapi_options = Some(value);
43 self
44 }
45
46 pub fn build(self, authentication: &impl Authentication) -> RequestBuilder {
47 let client = reqwest::Client::new();
48 let url = make_url(&self.twapi_options, URL);
49 let builder = client.post(&url).multipart(self.form.make_form());
50 authentication.execute(
51 apply_options(builder, &self.twapi_options),
52 "POST",
53 &url,
54 &[],
55 )
56 }
57
58 pub async fn execute(
59 self,
60 authentication: &impl Authentication,
61 ) -> Result<(Response, Headers), Error> {
62 execute_twitter(self.build(authentication)).await
63 }
64}
65
66#[derive(Serialize, Deserialize, Debug, Clone, Default)]
67pub struct Response {
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub data: Option<MediaUpload>,
70 #[serde(skip_serializing_if = "Option::is_none")]
71 pub errors: Option<Vec<Errors>>,
72 #[serde(flatten)]
73 pub extra: std::collections::HashMap<String, serde_json::Value>,
74}
75
76impl Response {
77 pub fn is_empty_extra(&self) -> bool {
78 let res = self.extra.is_empty()
79 && self
80 .data
81 .as_ref()
82 .map(|it| it.is_empty_extra())
83 .unwrap_or(true)
84 && self
85 .errors
86 .as_ref()
87 .map(|it| it.iter().all(|item| item.is_empty_extra()))
88 .unwrap_or(true);
89 if !res {
90 println!("Response {:?}", self.extra);
91 }
92 res
93 }
94}