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, 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(builder, "POST", &url, &[])
102    }
103
104    pub async fn execute(
105        &self,
106        authentication: &impl Authentication,
107    ) -> Result<(Response, Headers), Error> {
108        execute_twitter(|| self.build(authentication), &self.twapi_options).await
109    }
110}
111
112#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
113pub struct Response {
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub data: Option<Data>,
116    #[serde(flatten)]
117    pub extra: std::collections::HashMap<String, serde_json::Value>,
118}
119
120impl Response {
121    pub fn is_empty_extra(&self) -> bool {
122        let res = self.extra.is_empty()
123            && self
124                .data
125                .as_ref()
126                .map(|it| it.is_empty_extra())
127                .unwrap_or(true);
128        if !res {
129            println!("Response {:?}", self.extra);
130        }
131        res
132    }
133}
134
135#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
136pub struct Data {
137    #[serde(skip_serializing_if = "Option::is_none")]
138    pub associated_metadata: Option<AssociatedMetadata>,
139    #[serde(skip_serializing_if = "Option::is_none")]
140    pub id: Option<String>,
141    #[serde(flatten)]
142    pub extra: std::collections::HashMap<String, serde_json::Value>,
143}
144
145impl Data {
146    pub fn is_empty_extra(&self) -> bool {
147        let res = self.extra.is_empty()
148            && self
149                .associated_metadata
150                .as_ref()
151                .map(|it| it.is_empty_extra())
152                .unwrap_or(true);
153        if !res {
154            println!("Data {:?}", self.extra);
155        }
156        res
157    }
158}