Skip to main content

twapi_v2/api/
post_2_users_id_following.rs

1use crate::responses::errors::Errors;
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/users/:id/following";
11
12#[derive(Serialize, Deserialize, Debug, Default, Clone)]
13pub struct Body {
14    pub target_user_id: String,
15}
16
17#[derive(Debug, Clone, Default)]
18pub struct Api {
19    id: String,
20    body: Body,
21    twapi_options: Option<TwapiOptions>,
22}
23
24impl Api {
25    pub fn new(id: &str, body: Body) -> Self {
26        Self {
27            id: id.to_owned(),
28            body,
29            ..Default::default()
30        }
31    }
32
33    pub fn twapi_options(mut self, value: TwapiOptions) -> Self {
34        self.twapi_options = Some(value);
35        self
36    }
37
38    pub fn build(self, authentication: &impl Authentication) -> RequestBuilder {
39        let client = reqwest::Client::new();
40        let url = make_url(&self.twapi_options, &URL.replace(":id", &self.id));
41        let builder = client.post(&url).json(&self.body);
42        authentication.execute(
43            apply_options(builder, &self.twapi_options),
44            "POST",
45            &url,
46            &[],
47        )
48    }
49
50    pub async fn execute(
51        self,
52        authentication: &impl Authentication,
53    ) -> Result<(Response, Headers), Error> {
54        execute_twitter(self.build(authentication)).await
55    }
56}
57
58#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
59pub struct Response {
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub data: Option<Data>,
62    #[serde(skip_serializing_if = "Option::is_none")]
63    pub errors: Option<Vec<Errors>>,
64    #[serde(flatten)]
65    pub extra: std::collections::HashMap<String, serde_json::Value>,
66}
67
68impl Response {
69    pub fn is_empty_extra(&self) -> bool {
70        let res = self.extra.is_empty()
71            && self
72                .data
73                .as_ref()
74                .map(|it| it.is_empty_extra())
75                .unwrap_or(true)
76            && self
77                .errors
78                .as_ref()
79                .map(|it| it.iter().all(|item| item.is_empty_extra()))
80                .unwrap_or(true);
81        if !res {
82            println!("Response {:?}", self.extra);
83        }
84        res
85    }
86}
87
88#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
89pub struct Data {
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub following: Option<bool>,
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub pending_follow: Option<bool>,
94    #[serde(flatten)]
95    pub extra: std::collections::HashMap<String, serde_json::Value>,
96}
97
98impl Data {
99    pub fn is_empty_extra(&self) -> bool {
100        let res = self.extra.is_empty();
101        if !res {
102            println!("Data {:?}", self.extra);
103        }
104        res
105    }
106}