diff options
author | Ilion Beyst <ilion.beyst@gmail.com> | 2022-08-16 19:23:53 +0200 |
---|---|---|
committer | Ilion Beyst <ilion.beyst@gmail.com> | 2022-08-16 19:23:53 +0200 |
commit | 03ca884c4049f289d9b7c4700a2142967772fb4d (patch) | |
tree | 8ac21b0b4d93514d2e2137b1fba5d12f2ddfdcf2 | |
parent | a1c7866f87872e83e7766f76eae443fd5af59fd7 (diff) | |
download | planetwars.dev-03ca884c4049f289d9b7c4700a2142967772fb4d.tar.xz planetwars.dev-03ca884c4049f289d9b7c4700a2142967772fb4d.zip |
return pagination object from list matches API
-rw-r--r-- | planetwars-server/src/routes/matches.rs | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/planetwars-server/src/routes/matches.rs b/planetwars-server/src/routes/matches.rs index 1b7581c..44bdaf1 100644 --- a/planetwars-server/src/routes/matches.rs +++ b/planetwars-server/src/routes/matches.rs @@ -44,16 +44,25 @@ pub struct ListRecentMatchesParams { const MAX_NUM_RETURNED_MATCHES: usize = 100; const DEFAULT_NUM_RETURNED_MATCHES: usize = 50; +#[derive(Serialize, Deserialize)] +pub struct ListMatchesResponse { + matches: Vec<ApiMatch>, + has_next: bool, +} + pub async fn list_recent_matches( Query(params): Query<ListRecentMatchesParams>, conn: DatabaseConnection, -) -> Result<Json<Vec<ApiMatch>>, StatusCode> { - let count = std::cmp::min( +) -> Result<Json<ListMatchesResponse>, StatusCode> { + let requested_count = std::cmp::min( params.count.unwrap_or(DEFAULT_NUM_RETURNED_MATCHES), MAX_NUM_RETURNED_MATCHES, - ) as i64; + ); + + // fetch one additional record to check whether a next page exists + let count = (requested_count + 1) as i64; - let matches = match params.bot { + let matches_result = match params.bot { Some(bot_name) => { let bot = db::bots::find_bot_by_name(&bot_name, &conn) .map_err(|_| StatusCode::BAD_REQUEST)?; @@ -62,9 +71,23 @@ pub async fn list_recent_matches( None => matches::list_public_matches(count, params.before, params.after, &conn), }; - matches - .map_err(|_| StatusCode::BAD_REQUEST) - .map(|matches| Json(matches.into_iter().map(match_data_to_api).collect())) + let mut matches = matches_result.map_err(|_| StatusCode::BAD_REQUEST)?; + + let mut has_next = false; + if matches.len() > requested_count { + has_next = true; + matches.truncate(requested_count); + } + + let api_matches = matches + .into_iter() + .map(match_data_to_api) + .collect(); + + Ok(Json(ListMatchesResponse { + matches: api_matches, + has_next, + })) } pub fn match_data_to_api(data: matches::FullMatchData) -> ApiMatch { |