Skip to content

Commit cd4df91

Browse files
committed
complete v2 API coverage
1 parent 9c1ffb0 commit cd4df91

File tree

6 files changed

+215
-41
lines changed

6 files changed

+215
-41
lines changed

src/client.rs

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use crate::filters::{EventTeamsFilter, EventSkillsFilter, EventAwardsFilter, DivisionMatchesFilter, DivisionRankingsFilter, TeamEventsFilter, TeamMatchesFilter, TeamRankingsFilter, TeamSkillsFilter, TeamAwardsFilter, SeasonEventsFilter};
2+
13
use super::{
24
filters::{EventsFilter, SeasonsFilter, TeamsFilter},
35
schema::*,
@@ -69,6 +71,7 @@ impl RobotEvents {
6971
.json()
7072
.await?)
7173
}
74+
7275
/// Get a specific RobotEvents [`Team`] by ID.
7376
pub async fn team(&self, team_id: i32) -> Result<Team, reqwest::Error> {
7477
Ok(self
@@ -78,6 +81,51 @@ impl RobotEvents {
7881
.await?)
7982
}
8083

84+
/// Gets a List of Events that a given Team has attended.
85+
pub async fn team_events(&self, team_id: i32, filter: TeamEventsFilter) -> Result<PaginatedResponse<Event>, reqwest::Error> {
86+
Ok(self
87+
.request(format!("/teams/{team_id}/events{filter}"))
88+
.await?
89+
.json()
90+
.await?)
91+
}
92+
93+
/// Gets a List of Matches that a given Team has played in.
94+
pub async fn team_matches(&self, team_id: i32, filter: TeamMatchesFilter) -> Result<PaginatedResponse<Match>, reqwest::Error> {
95+
Ok(self
96+
.request(format!("/teams/{team_id}/matches{filter}"))
97+
.await?
98+
.json()
99+
.await?)
100+
}
101+
102+
/// Gets a List of Matches that a given Team has played in.
103+
pub async fn team_rankings(&self, team_id: i32, filter: TeamRankingsFilter) -> Result<PaginatedResponse<Ranking>, reqwest::Error> {
104+
Ok(self
105+
.request(format!("/teams/{team_id}/rankings{filter}"))
106+
.await?
107+
.json()
108+
.await?)
109+
}
110+
111+
/// Gets a List of Skills runs that a given Team has performed.
112+
pub async fn team_skills(&self, team_id: i32, filter: TeamSkillsFilter) -> Result<PaginatedResponse<Skill>, reqwest::Error> {
113+
Ok(self
114+
.request(format!("/teams/{team_id}/skills{filter}"))
115+
.await?
116+
.json()
117+
.await?)
118+
}
119+
120+
/// Gets a List of Awards that a given Team has received.
121+
pub async fn team_awards(&self, team_id: i32, filter: TeamAwardsFilter) -> Result<PaginatedResponse<Award>, reqwest::Error> {
122+
Ok(self
123+
.request(format!("/teams/{team_id}/awards{filter}"))
124+
.await?
125+
.json()
126+
.await?)
127+
}
128+
81129
/// Get a paginated list of [`Season`]s from RobotEvents.
82130
///
83131
/// Season listings can be filtered using a [`SeasonFilter`] search.
@@ -91,6 +139,7 @@ impl RobotEvents {
91139
.json()
92140
.await?)
93141
}
142+
94143
/// Get a specific RobotEvents [`Season`] by ID.
95144
pub async fn season(&self, season_id: i32) -> Result<Season, reqwest::Error> {
96145
Ok(self
@@ -100,6 +149,15 @@ impl RobotEvents {
100149
.await?)
101150
}
102151

152+
/// Gets a List of Events for a given Season.
153+
pub async fn season_events(&self, season_id: i32, filter: SeasonEventsFilter) -> Result<PaginatedResponse<Season>, reqwest::Error> {
154+
Ok(self
155+
.request(format!("/seasons/{season_id}/events{filter}"))
156+
.await?
157+
.json()
158+
.await?)
159+
}
160+
103161
/// Get a paginated list of all programs from RobotEvents.
104162
pub async fn programs(&self) -> Result<PaginatedResponse<IdInfo>, reqwest::Error> {
105163
Ok(self.request("/programs").await?.json().await?)
@@ -121,15 +179,70 @@ impl RobotEvents {
121179
filter: EventsFilter,
122180
) -> Result<PaginatedResponse<Event>, reqwest::Error> {
123181
Ok(self
124-
.request(format!("/programs{filter}"))
182+
.request(format!("/events{filter}"))
125183
.await?
126184
.json()
127185
.await?)
128186
}
187+
129188
/// Get a specific RobotEvents event by ID.
130189
pub async fn event(&self, event_id: i32) -> Result<Event, reqwest::Error> {
131190
Ok(self
132-
.request(format!("/programs/{event_id}"))
191+
.request(format!("/events/{event_id}"))
192+
.await?
193+
.json()
194+
.await?)
195+
}
196+
197+
/// Get a paginated list of teams attending an event.
198+
pub async fn event_teams(&self, event_id: i32, filter: EventTeamsFilter) -> Result<PaginatedResponse<Team>, reqwest::Error> {
199+
Ok(self
200+
.request(format!("/events/{event_id}/teams{filter}"))
201+
.await?
202+
.json()
203+
.await?)
204+
}
205+
206+
/// Get a paginated list of skills runs at an event.
207+
pub async fn event_skills(&self, event_id: i32, filter: EventSkillsFilter) -> Result<PaginatedResponse<Skill>, reqwest::Error> {
208+
Ok(self
209+
.request(format!("/events/{event_id}/skills{filter}"))
210+
.await?
211+
.json()
212+
.await?)
213+
}
214+
215+
/// Get a paginated list of skills runs at an event.
216+
pub async fn event_awards(&self, event_id: i32, filter: EventAwardsFilter) -> Result<PaginatedResponse<Award>, reqwest::Error> {
217+
Ok(self
218+
.request(format!("/events/{event_id}/awards{filter}"))
219+
.await?
220+
.json()
221+
.await?)
222+
}
223+
224+
/// Gets a List of Matches for a single Division of an Event.
225+
pub async fn event_division_matches(&self, event_id: i32, division_id: i32, filter: DivisionMatchesFilter) -> Result<PaginatedResponse<Match>, reqwest::Error> {
226+
Ok(self
227+
.request(format!("/events/{event_id}/divisions/{division_id}/matches{filter}"))
228+
.await?
229+
.json()
230+
.await?)
231+
}
232+
233+
/// Gets a List of Finalist Rankings for a single Division of an Event.
234+
pub async fn event_division_finalist_rankings(&self, event_id: i32, division_id: i32, filter: DivisionRankingsFilter) -> Result<PaginatedResponse<Ranking>, reqwest::Error> {
235+
Ok(self
236+
.request(format!("/events/{event_id}/divisions/{division_id}/finalistRankings{filter}"))
237+
.await?
238+
.json()
239+
.await?)
240+
}
241+
242+
/// Gets a List of Rankings for a single Division of an Event.
243+
pub async fn event_division_rankings(&self, event_id: i32, division_id: i32, filter: DivisionRankingsFilter) -> Result<PaginatedResponse<Ranking>, reqwest::Error> {
244+
Ok(self
245+
.request(format!("/events/{event_id}/divisions/{division_id}/finalist{filter}"))
133246
.await?
134247
.json()
135248
.await?)

src/filters/event.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::impl_filter_display;
22
use itertools::join;
33
use std::collections::HashMap;
44

5-
use crate::schema::{EventLevel, EventType, Grade, MatchRound};
5+
use crate::schema::{EventLevel, EventType, Grade, MatchRound, SkillType};
66

77
/// Filters for the RobotEvents `/events` endpoint.
88
#[derive(Default, Debug, Clone, PartialEq)]
@@ -143,6 +143,38 @@ impl EventTeamsFilter {
143143
}
144144
}
145145

146+
/// Filters for the RobotEvents `/events/:id/skills` endpoint.
147+
#[derive(Default, Debug, Clone, PartialEq)]
148+
pub struct EventSkillsFilter {
149+
query: HashMap<&'static str, String>,
150+
}
151+
152+
impl_filter_display!(EventSkillsFilter);
153+
154+
impl EventSkillsFilter {
155+
pub fn new() -> Self {
156+
Self::default()
157+
}
158+
159+
pub fn team(mut self, team: i32) -> Self {
160+
self.query.insert("team%5B%5D", team.to_string());
161+
self
162+
}
163+
pub fn teams(mut self, teams: &[i32]) -> Self {
164+
self.query.insert("team%5B%5D", join(teams, ","));
165+
self
166+
}
167+
168+
pub fn skill_type(mut self, skill_type: SkillType) -> Self {
169+
self.query.insert("type%5B%5D", skill_type.to_string());
170+
self
171+
}
172+
pub fn skill_types(mut self, skill_types: &[SkillType]) -> Self {
173+
self.query.insert("type%5B%5D", join(skill_types, ","));
174+
self
175+
}
176+
}
177+
146178
/// Filters for the RobotEvents `/event/:id/awards` endpoint.
147179
#[derive(Default, Debug, Clone, PartialEq)]
148180
pub struct EventAwardsFilter {

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ pub mod client;
22
pub mod filters;
33
pub mod schema;
44

5-
pub use client::*;
5+
pub use client::*;

src/schema/event.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
use super::{IdInfo, Location, Season};
1+
use crate::{
2+
RobotEvents,
3+
filters::{EventTeamsFilter, EventSkillsFilter, EventAwardsFilter, DivisionMatchesFilter, DivisionRankingsFilter},
4+
schema::{IdInfo, Location, Season}
5+
};
6+
27
use serde::{Deserialize, Serialize};
38

9+
use super::{PaginatedResponse, Team, Skill, Award, Match, Ranking};
10+
411
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
512
pub struct Division {
613
id: i32,
@@ -68,3 +75,51 @@ pub struct Event {
6875
pub awards_finalized: bool,
6976
pub event_type: EventType,
7077
}
78+
79+
impl Event {
80+
pub async fn teams(
81+
&self,
82+
client: &RobotEvents,
83+
filter: EventTeamsFilter,
84+
) -> Result<PaginatedResponse<Team>, reqwest::Error> {
85+
client.event_teams(self.id, filter).await
86+
}
87+
pub async fn skills(
88+
&self,
89+
client: &RobotEvents,
90+
filter: EventSkillsFilter,
91+
) -> Result<PaginatedResponse<Skill>, reqwest::Error> {
92+
client.event_skills(self.id, filter).await
93+
}
94+
pub async fn awards(
95+
&self,
96+
client: &RobotEvents,
97+
filter: EventAwardsFilter,
98+
) -> Result<PaginatedResponse<Award>, reqwest::Error> {
99+
client.event_awards(self.id, filter).await
100+
}
101+
pub async fn division_matches(
102+
&self,
103+
division_id: i32,
104+
client: &RobotEvents,
105+
filter: DivisionMatchesFilter,
106+
) -> Result<PaginatedResponse<Match>, reqwest::Error> {
107+
client.event_division_matches(self.id, division_id, filter).await
108+
}
109+
pub async fn division_finalist_rankings(
110+
&self,
111+
division_id: i32,
112+
client: &RobotEvents,
113+
filter: DivisionRankingsFilter,
114+
) -> Result<PaginatedResponse<Ranking>, reqwest::Error> {
115+
client.event_division_finalist_rankings(self.id, division_id, filter).await
116+
}
117+
pub async fn division_rankings(
118+
&self,
119+
division_id: i32,
120+
client: &RobotEvents,
121+
filter: DivisionRankingsFilter,
122+
) -> Result<PaginatedResponse<Ranking>, reqwest::Error> {
123+
client.event_division_rankings(self.id, division_id, filter).await
124+
}
125+
}

src/schema/mod.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ impl<T: DeserializeOwned> PaginatedResponse<T> {
5050
.request(url.trim_start_matches(V2_API_BASE))
5151
.await
5252
{
53-
Ok(response) => match response.json::<PaginatedResponse<T>>().await {
53+
Ok(response) => match response.json().await {
5454
Ok(json) => Some(Ok(json)),
5555
Err(error) => Some(Err(error)),
5656
},
@@ -70,7 +70,7 @@ impl<T: DeserializeOwned> PaginatedResponse<T> {
7070
.request(url.trim_start_matches(V2_API_BASE))
7171
.await
7272
{
73-
Ok(response) => match response.json::<PaginatedResponse<T>>().await {
73+
Ok(response) => match response.json().await {
7474
Ok(json) => Some(Ok(json)),
7575
Err(error) => Some(Err(error)),
7676
},
@@ -88,7 +88,7 @@ impl<T: DeserializeOwned> PaginatedResponse<T> {
8888
robotevents
8989
.request(self.meta.first_page_url.trim_start_matches(V2_API_BASE))
9090
.await?
91-
.json::<PaginatedResponse<T>>()
91+
.json()
9292
.await
9393
}
9494

@@ -99,7 +99,7 @@ impl<T: DeserializeOwned> PaginatedResponse<T> {
9999
robotevents
100100
.request(self.meta.last_page_url.trim_start_matches(V2_API_BASE))
101101
.await?
102-
.json::<PaginatedResponse<T>>()
102+
.json()
103103
.await
104104
}
105105
}
@@ -135,10 +135,4 @@ impl std::fmt::Display for Grade {
135135
Self::ElementarySchool => "Elementary School",
136136
})
137137
}
138-
}
139-
140-
// #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
141-
// pub struct Error {
142-
// pub code: i32,
143-
// pub message: String,
144-
// }
138+
}

src/schema/team.rs

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,54 +26,34 @@ impl Team {
2626
client: &RobotEvents,
2727
filter: TeamEventsFilter,
2828
) -> Result<PaginatedResponse<Event>, reqwest::Error> {
29-
Ok(client
30-
.request(format!("/teams/{}/events{filter}", self.id))
31-
.await?
32-
.json()
33-
.await?)
29+
client.team_events(self.id, filter).await
3430
}
3531
pub async fn matches(
3632
&self,
3733
client: &RobotEvents,
3834
filter: TeamMatchesFilter,
3935
) -> Result<PaginatedResponse<Match>, reqwest::Error> {
40-
Ok(client
41-
.request(format!("/teams/{}/matches{filter}", self.id))
42-
.await?
43-
.json()
44-
.await?)
36+
client.team_matches(self.id, filter).await
4537
}
4638
pub async fn rankings(
4739
&self,
4840
client: &RobotEvents,
4941
filter: TeamRankingsFilter,
5042
) -> Result<PaginatedResponse<Ranking>, reqwest::Error> {
51-
Ok(client
52-
.request(format!("/teams/{}/rankings{filter}", self.id))
53-
.await?
54-
.json()
55-
.await?)
43+
client.team_rankings(self.id, filter).await
5644
}
5745
pub async fn skills(
5846
&self,
5947
client: &RobotEvents,
6048
filter: TeamSkillsFilter,
6149
) -> Result<PaginatedResponse<Skill>, reqwest::Error> {
62-
Ok(client
63-
.request(format!("/teams/{}/skills{filter}", self.id))
64-
.await?
65-
.json()
66-
.await?)
50+
client.team_skills(self.id, filter).await
6751
}
6852
pub async fn awards(
6953
&self,
7054
client: &RobotEvents,
7155
filter: TeamAwardsFilter,
7256
) -> Result<PaginatedResponse<Award>, reqwest::Error> {
73-
Ok(client
74-
.request(format!("/teams/{}/awards{filter}", self.id))
75-
.await?
76-
.json()
77-
.await?)
57+
client.team_awards(self.id, filter).await
7858
}
7959
}

0 commit comments

Comments
 (0)