Skip to main content

twapi_v2/api/
get_2_users_id_pinned_lists.rs

1use crate::fields::{list_fields::ListFields, user_fields::UserFields};
2use crate::responses::{errors::Errors, includes::Includes, memberships::Memberships, meta::Meta};
3use crate::{
4    api::{Authentication, TwapiOptions, execute_twitter, make_url},
5    error::Error,
6    headers::Headers,
7};
8use itertools::Itertools;
9use reqwest::RequestBuilder;
10use serde::{Deserialize, Serialize};
11use std::collections::HashSet;
12
13const URL: &str = "/2/users/:id/pinned_lists";
14
15#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Clone)]
16#[derive(Default)]
17pub enum Expansions {
18    #[serde(rename = "owner_id")]
19    #[default]
20    OwnerId,
21}
22
23impl Expansions {
24    pub fn all() -> HashSet<Self> {
25        let mut result = HashSet::new();
26        result.insert(Self::OwnerId);
27        result
28    }
29}
30
31impl std::fmt::Display for Expansions {
32    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
33        match self {
34            Self::OwnerId => write!(f, "owner_id"),
35        }
36    }
37}
38
39
40#[derive(Debug, Clone, Default)]
41pub struct Api {
42    id: String,
43    expansions: Option<HashSet<Expansions>>,
44    list_fields: Option<HashSet<ListFields>>,
45    user_fields: Option<HashSet<UserFields>>,
46    twapi_options: Option<TwapiOptions>,
47}
48
49impl Api {
50    pub fn new(id: &str) -> Self {
51        Self {
52            id: id.to_owned(),
53            ..Default::default()
54        }
55    }
56
57    pub fn all(id: &str) -> Self {
58        Self {
59            id: id.to_owned(),
60            expansions: Some(Expansions::all()),
61            list_fields: Some(ListFields::all()),
62            user_fields: Some(UserFields::all()),
63            ..Default::default()
64        }
65    }
66
67    pub fn expansions(mut self, value: HashSet<Expansions>) -> Self {
68        self.expansions = Some(value);
69        self
70    }
71
72    pub fn list_fields(mut self, value: HashSet<ListFields>) -> Self {
73        self.list_fields = Some(value);
74        self
75    }
76
77    pub fn user_fields(mut self, value: HashSet<UserFields>) -> Self {
78        self.user_fields = Some(value);
79        self
80    }
81
82    pub fn twapi_options(mut self, value: TwapiOptions) -> Self {
83        self.twapi_options = Some(value);
84        self
85    }
86
87    pub fn build(&self, authentication: &impl Authentication) -> RequestBuilder {
88        let mut query_parameters = vec![];
89        if let Some(expansions) = self.expansions.as_ref() {
90            query_parameters.push(("expansions", expansions.iter().join(",")));
91        }
92        if let Some(list_fields) = self.list_fields.as_ref() {
93            query_parameters.push(("list.fields", list_fields.iter().join(",")));
94        }
95        if let Some(user_fields) = self.user_fields.as_ref() {
96            query_parameters.push(("user.fields", user_fields.iter().join(",")));
97        }
98        let client = reqwest::Client::new();
99        let url = make_url(&self.twapi_options, &URL.replace(":id", &self.id));
100        let builder = client.get(&url).query(&query_parameters);
101        authentication.execute(
102            builder,
103            "GET",
104            &url,
105            &query_parameters
106                .iter()
107                .map(|it| (it.0, it.1.as_str()))
108                .collect::<Vec<_>>(),
109        )
110    }
111
112    pub async fn execute(
113        &self,
114        authentication: &impl Authentication,
115    ) -> Result<(Response, Headers), Error> {
116        execute_twitter(|| self.build(authentication), &self.twapi_options).await
117    }
118}
119
120#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
121pub struct Response {
122    #[serde(skip_serializing_if = "Option::is_none")]
123    pub data: Option<Vec<Memberships>>,
124    #[serde(skip_serializing_if = "Option::is_none")]
125    pub errors: Option<Vec<Errors>>,
126    #[serde(skip_serializing_if = "Option::is_none")]
127    pub includes: Option<Includes>,
128    #[serde(skip_serializing_if = "Option::is_none")]
129    pub meta: Option<Meta>,
130    #[serde(flatten)]
131    pub extra: std::collections::HashMap<String, serde_json::Value>,
132}
133
134impl Response {
135    pub fn is_empty_extra(&self) -> bool {
136        let res = self.extra.is_empty()
137            && self
138                .data
139                .as_ref()
140                .map(|it| it.iter().all(|item| item.is_empty_extra()))
141                .unwrap_or(true)
142            && self
143                .errors
144                .as_ref()
145                .map(|it| it.iter().all(|item| item.is_empty_extra()))
146                .unwrap_or(true)
147            && self
148                .includes
149                .as_ref()
150                .map(|it| it.is_empty_extra())
151                .unwrap_or(true)
152            && self
153                .meta
154                .as_ref()
155                .map(|it| it.is_empty_extra())
156                .unwrap_or(true);
157        if !res {
158            println!("Response {:?}", self.extra);
159        }
160        res
161    }
162}