Skip to main content

twapi_v2/api/
get_2_tweets_count_all.rs

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