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