Skip to main content

twapi_v2/api/
post_2_media_metadata_create.rs

1use crate::responses::associated_metadata::AssociatedMetadata;
2use crate::{
3    api::{Authentication, TwapiOptions, apply_options, execute_twitter, make_url},
4    error::Error,
5    headers::Headers,
6};
7use reqwest::RequestBuilder;
8use serde::{Deserialize, Serialize};
9
10const URL: &str = "/2/media/metadata/create";
11
12#[derive(Serialize, Deserialize, Debug, Default, Clone)]
13pub struct AllowDownloadStatus {
14    pub allow_download: bool,
15}
16
17#[derive(Serialize, Deserialize, Debug, Default, Clone)]
18pub struct AltText {
19    pub text: String,
20}
21
22#[derive(Serialize, Deserialize, Debug, Default, Clone)]
23pub struct FoundMediaOrigin {
24    pub id: String,
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub provider: Option<String>,
27}
28
29#[derive(Serialize, Deserialize, Debug, Default, Clone)]
30pub struct Sticker {
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub aspect_ratio: Option<String>,
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub group_annotation_id: Option<String>,
35    pub id: String,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub sticker_set_annotation_id: Option<String>,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub transform_a: Option<String>,
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub transform_b: Option<String>,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub transform_c: Option<String>,
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub transform_d: Option<String>,
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub transform_tx: Option<String>,
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub transform_ty: Option<String>,
50}
51
52#[derive(Serialize, Deserialize, Debug, Default, Clone)]
53pub struct StickerInfo {
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub stickers: Option<Vec<Sticker>>,
56}
57
58#[derive(Serialize, Deserialize, Debug, Default, Clone)]
59pub struct UploadSource {
60    pub text: String,
61}
62
63#[derive(Serialize, Deserialize, Debug, Default, Clone)]
64pub struct Body {
65    pub media_id: String,
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub allow_download_status: Option<AllowDownloadStatus>,
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub alt_text: Option<AltText>,
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub found_media_origin: Option<FoundMediaOrigin>,
72    #[serde(skip_serializing_if = "Option::is_none")]
73    pub sticker_info: Option<StickerInfo>,
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub upload_source: Option<UploadSource>,
76}
77
78#[derive(Debug, Clone, Default)]
79pub struct Api {
80    body: Body,
81    twapi_options: Option<TwapiOptions>,
82}
83
84impl Api {
85    pub fn new(body: Body) -> Self {
86        Self {
87            body,
88            ..Default::default()
89        }
90    }
91
92    pub fn twapi_options(mut self, value: TwapiOptions) -> Self {
93        self.twapi_options = Some(value);
94        self
95    }
96
97    pub fn build(self, authentication: &impl Authentication) -> RequestBuilder {
98        let client = reqwest::Client::new();
99        let url = make_url(&self.twapi_options, URL);
100        let builder = client.post(&url).json(&self.body);
101        authentication.execute(
102            apply_options(builder, &self.twapi_options),
103            "POST",
104            &url,
105            &[],
106        )
107    }
108
109    pub async fn execute(
110        self,
111        authentication: &impl Authentication,
112    ) -> Result<(Response, Headers), Error> {
113        execute_twitter(self.build(authentication)).await
114    }
115}
116
117#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
118pub struct Response {
119    #[serde(skip_serializing_if = "Option::is_none")]
120    pub data: Option<Data>,
121    #[serde(flatten)]
122    pub extra: std::collections::HashMap<String, serde_json::Value>,
123}
124
125impl Response {
126    pub fn is_empty_extra(&self) -> bool {
127        let res = self.extra.is_empty()
128            && self
129                .data
130                .as_ref()
131                .map(|it| it.is_empty_extra())
132                .unwrap_or(true);
133        if !res {
134            println!("Response {:?}", self.extra);
135        }
136        res
137    }
138}
139
140#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
141pub struct Data {
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub associated_metadata: Option<AssociatedMetadata>,
144    #[serde(skip_serializing_if = "Option::is_none")]
145    pub id: Option<String>,
146    #[serde(flatten)]
147    pub extra: std::collections::HashMap<String, serde_json::Value>,
148}
149
150impl Data {
151    pub fn is_empty_extra(&self) -> bool {
152        let res = self.extra.is_empty()
153            && self
154                .associated_metadata
155                .as_ref()
156                .map(|it| it.is_empty_extra())
157                .unwrap_or(true);
158        if !res {
159            println!("Data {:?}", self.extra);
160        }
161        res
162    }
163}