twapi_v2/api/
post_2_media_upload_initialize.rs1use crate::responses::errors::Errors;
2use crate::responses::media_upload::MediaUpload;
3use crate::{
4 api::{Authentication, TwapiOptions, apply_options, execute_twitter, make_url},
5 error::Error,
6 headers::Headers,
7};
8use reqwest::RequestBuilder;
9use serde::{Deserialize, Serialize};
10
11const URL: &str = "/2/media/upload/initialize";
12
13#[derive(Serialize, Deserialize, Debug, Clone)]
14#[serde(rename_all = "snake_case")]
15pub enum MediaCategory {
16 AmplifyVideo,
17 TweetGif,
18 TweetImage,
19 TweetVideo,
20 DmVideo,
21 DmImage,
22 Subtitles,
23 DmGif,
24}
25
26#[derive(Serialize, Deserialize, Debug, Clone, Default)]
27pub struct Body {
28 pub total_bytes: u64,
29 pub media_type: String,
30 pub media_category: Option<MediaCategory>,
31 pub additional_owners: Vec<String>,
32}
33
34#[derive(Debug, Clone, Default)]
35pub struct Api {
36 body: Body,
37 twapi_options: Option<TwapiOptions>,
38}
39
40impl Api {
41 pub fn new(body: Body) -> Self {
42 Self {
43 body,
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 client = reqwest::Client::new();
55 let url = make_url(&self.twapi_options, URL);
56 let builder = client.post(&url).json(&self.body);
57 authentication.execute(
58 apply_options(builder, &self.twapi_options),
59 "POST",
60 &url,
61 &[],
62 )
63 }
64
65 pub async fn execute(
66 self,
67 authentication: &impl Authentication,
68 ) -> Result<(Response, Headers), Error> {
69 execute_twitter(self.build(authentication)).await
70 }
71}
72
73#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
74pub struct Response {
75 #[serde(skip_serializing_if = "Option::is_none")]
76 pub data: Option<MediaUpload>,
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub errors: Option<Vec<Errors>>,
79 #[serde(flatten)]
80 pub extra: std::collections::HashMap<String, serde_json::Value>,
81}
82
83impl Response {
84 pub fn is_empty_extra(&self) -> bool {
85 let res = self.extra.is_empty()
86 && self
87 .data
88 .as_ref()
89 .map(|it| it.is_empty_extra())
90 .unwrap_or(true)
91 && self
92 .errors
93 .as_ref()
94 .map(|it| it.iter().all(|item| item.is_empty_extra()))
95 .unwrap_or(true);
96 if !res {
97 println!("Response {:?}", self.extra);
98 }
99 res
100 }
101}