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