1use crate::VotesmartProxy;
2use reqwest::{Error, Response};
3
4pub struct Votes<'a>(pub &'a VotesmartProxy);
5
6impl Votes<'_> {
7 pub async fn get_categories(
9 &self,
10 year: i32,
11 state_id: Option<&str>,
12 ) -> Result<Response, Error> {
13 let url = format!(
14 "{base_url}{operation}?key={key}&year={year}&stateId={state_id}&o=JSON",
15 base_url = &self.0.base_url,
16 key = &self.0.api_key,
17 operation = "Votes.getCategories",
18 year = year,
19 state_id = state_id.unwrap_or("")
20 );
21
22 self.0.client.get(url).send().await
23 }
24
25 pub async fn get_bill(&self, bill_id: i32) -> Result<Response, Error> {
27 let url = format!(
28 "{base_url}{operation}?key={key}&billId={bill_id}&o=JSON",
29 base_url = &self.0.base_url,
30 key = &self.0.api_key,
31 operation = "Votes.getBill",
32 bill_id = bill_id,
33 );
34
35 self.0.client.get(url).send().await
36 }
37
38 pub async fn get_bill_action(&self, action_id: i32) -> Result<Response, Error> {
40 let url = format!(
41 "{base_url}{operation}?key={key}&actionId={action_id}&o=JSON",
42 base_url = &self.0.base_url,
43 key = &self.0.api_key,
44 operation = "Votes.getBillAction",
45 action_id = action_id,
46 );
47
48 self.0.client.get(url).send().await
49 }
50
51 pub async fn get_bill_action_votes(&self, action_id: i32) -> Result<Response, Error> {
53 let url = format!(
54 "{base_url}{operation}?key={key}&actionId={action_id}&o=JSON",
55 base_url = &self.0.base_url,
56 key = &self.0.api_key,
57 operation = "Votes.getBillActionVotes",
58 action_id = action_id,
59 );
60
61 self.0.client.get(url).send().await
62 }
63
64 pub async fn get_bill_action_vote_by_official(
66 &self,
67 action_id: i32,
68 candidate_id: i32,
69 ) -> Result<Response, Error> {
70 let url = format!(
71 "{base_url}{operation}?key={key}&actionId={action_id}&candidateId={candidate_id}&o=JSON",
72 base_url = &self.0.base_url,
73 key = &self.0.api_key,
74 operation = "Votes.getBillActionVotesByOfficial",
75 action_id = action_id,
76 candidate_id = candidate_id
77 );
78
79 self.0.client.get(url).send().await
80 }
81
82 pub async fn get_by_bill_number(&self, bill_number: String) -> Result<Response, Error> {
84 let url = format!(
85 "{base_url}{operation}?key={key}&billNumber={bill_number}&o=JSON",
86 base_url = &self.0.base_url,
87 key = &self.0.api_key,
88 operation = "Votes.getByBillNumber",
89 bill_number = bill_number,
90 );
91
92 self.0.client.get(url).send().await
93 }
94
95 pub async fn get_bills_by_category_year_state(
97 &self,
98 category_id: i32,
99 year: i32,
100 state_id: Option<&str>,
101 ) -> Result<Response, Error> {
102 let url = format!(
103 "{base_url}{operation}?key={key}&categoryId={category_id}&year={year}&stateId={state_id}&o=JSON",
104 base_url = &self.0.base_url,
105 key = &self.0.api_key,
106 operation = "Votes.getBillsByCategoryYearState",
107 category_id = category_id,
108 year = year,
109 state_id = state_id.unwrap_or("")
110 );
111
112 self.0.client.get(url).send().await
113 }
114
115 pub async fn get_bills_by_year_state(
117 &self,
118 year: i32,
119 state_id: Option<&str>,
120 ) -> Result<Response, Error> {
121 let url = format!(
122 "{base_url}{operation}?key={key}&year={year}&stateId={state_id}&o=JSON",
123 base_url = &self.0.base_url,
124 key = &self.0.api_key,
125 operation = "Votes.getBillsByYearState",
126 year = year,
127 state_id = state_id.unwrap_or("")
128 );
129
130 self.0.client.get(url).send().await
131 }
132
133 pub async fn get_bills_by_official_year_office(
135 &self,
136 candidate_id: i32,
137 year: i32,
138 office_id: Option<&str>,
139 ) -> Result<Response, Error> {
140 let url = format!(
141 "{base_url}{operation}?key={key}&candidateId={candidate_id}&year={year}&officeId={office_id}&o=JSON",
142 base_url = &self.0.base_url,
143 key = &self.0.api_key,
144 operation = "Votes.getByBillNumber",
145 candidate_id = candidate_id,
146 year = year,
147 office_id = office_id.unwrap_or("")
148 );
149
150 self.0.client.get(url).send().await
151 }
152
153 pub async fn get_bills_by_official_category_office(
155 &self,
156 candidate_id: i32,
157 category_id: i32,
158 office_id: Option<&str>,
159 ) -> Result<Response, Error> {
160 let url = format!(
161 "{base_url}{operation}?key={key}&candidateId={candidate_id}&categoryId={category_id}&officeId={office_id}&o=JSON",
162 base_url = &self.0.base_url,
163 key = &self.0.api_key,
164 operation = "Votes.getBillsByOfficialCategoryOffice",
165 candidate_id = candidate_id,
166 category_id = category_id,
167 office_id = office_id.unwrap_or("")
168 );
169
170 self.0.client.get(url).send().await
171 }
172
173 pub async fn get_by_official(
175 &self,
176 candidate_id: i32,
177 office_id: Option<&str>,
178 category_id: Option<&str>,
179 year: Option<&str>,
180 ) -> Result<Response, Error> {
181 let url = format!(
182 "{base_url}{operation}?key={key}&candidateId={candidate_id}&categoryId={category_id}&officeId={office_id}&year={year}&o=JSON",
183 base_url = &self.0.base_url,
184 key = &self.0.api_key,
185 operation = "Votes.getByOfficial",
186 candidate_id = candidate_id,
187 category_id = category_id.unwrap_or(""),
188 office_id = office_id.unwrap_or(""),
189 year = year.unwrap_or("")
190 );
191
192 self.0.client.get(url).send().await
193 }
194
195 pub async fn get_bills_by_sponsor_year(
197 &self,
198 candidate_id: i32,
199 year: i32,
200 ) -> Result<Response, Error> {
201 let url = format!(
202 "{base_url}{operation}?key={key}&candidateId={candidate_id}&year={year}&o=JSON",
203 base_url = &self.0.base_url,
204 key = &self.0.api_key,
205 operation = "Votes.getBillsBySponsorYear",
206 candidate_id = candidate_id,
207 year = year
208 );
209
210 self.0.client.get(url).send().await
211 }
212
213 pub async fn get_bills_by_sponsor_category(
215 &self,
216 candidate_id: i32,
217 category_id: i32,
218 ) -> Result<Response, Error> {
219 let url = format!(
220 "{base_url}{operation}?key={key}&candidateId={candidate_id}&categoryId={category_id}&o=JSON",
221 base_url = &self.0.base_url,
222 key = &self.0.api_key,
223 operation = "Votes.getBillsBySponsorCategory",
224 candidate_id = candidate_id,
225 category_id = category_id
226 );
227
228 self.0.client.get(url).send().await
229 }
230
231 pub async fn get_bills_by_state_recent(
233 &self,
234 state_id: String,
235 amount: Option<i32>,
236 ) -> Result<Response, Error> {
237 let url = format!(
238 "{base_url}{operation}?key={key}&state_id={state_id}&amount={amount}&o=JSON",
239 base_url = &self.0.base_url,
240 key = &self.0.api_key,
241 operation = "Votes.getBillsByStateRecent",
242 state_id = state_id,
243 amount = amount.unwrap_or(100)
244 );
245
246 self.0.client.get(url).send().await
247 }
248
249 pub async fn get_vetoes(&self, candidate_id: i32) -> Result<Response, Error> {
251 let url = format!(
252 "{base_url}{operation}?key={key}&candidateId={candidate_id}&o=JSON",
253 base_url = &self.0.base_url,
254 key = &self.0.api_key,
255 operation = "Votes.getVetoes",
256 candidate_id = candidate_id
257 );
258
259 self.0.client.get(url).send().await
260 }
261}
262
263#[cfg(test)]
264mod tests {
265 use crate::VotesmartProxy;
266
267 #[tokio::test]
268 async fn test_get_categories() {
269 let proxy = VotesmartProxy::new().unwrap();
270 let response = proxy.votes().get_categories(2020, None).await.unwrap();
271 assert!(response.status().is_success());
272 let json: serde_json::Value = response.json().await.unwrap();
273 assert_eq!(json["categories"]["category"][0]["name"], "Abortion");
274 }
275
276 #[tokio::test]
277 async fn test_get_bill() {
278 let proxy = VotesmartProxy::new().unwrap();
279 let response = proxy.votes().get_bill(32020).await.unwrap();
280 assert!(response.status().is_success());
281 let json: serde_json::Value = response.json().await.unwrap();
282 assert_eq!(
283 json["bill"]["title"],
284 "Joint resolution relating to increasing the debt limit"
285 );
286 }
287
288 #[tokio::test]
289 async fn test_get_bill_action() {
290 let proxy = VotesmartProxy::new().unwrap();
291 let response = proxy.votes().get_bill_action(83811).await.unwrap();
292 assert!(response.status().is_success());
293 let json: serde_json::Value = response.json().await.unwrap();
294 assert_eq!(json["action"]["billId"], "32020");
295 }
296}