use crate::data;
use crate::error::{ApiError, Result};
use crate::EndpointResult;
#[derive(serde_derive::Deserialize, Clone, Hash, Debug)]
#[doc(hidden)]
pub(crate) struct SingleResponse {
ok: i32,
rank: u32,
score: u64,
season: String,
user: String,
}
#[derive(serde_derive::Deserialize, Clone, Hash, Debug)]
#[doc(hidden)]
pub(crate) struct AllSeasonRanksResponse {
ok: i32,
list: Vec<InnerAllSeasonsResponse>,
}
#[derive(serde_derive::Deserialize, Clone, Hash, Debug)]
struct InnerAllSeasonsResponse {
rank: u32,
score: u64,
season: String,
user: String,
}
#[derive(Serialize, Deserialize, Clone, Hash, Debug)]
pub struct FoundUserRank {
pub season_id: String,
pub user_id: String,
pub rank: u32,
pub raw_score: u64,
#[serde(skip)]
pub(super) _non_exhaustive: (),
}
impl EndpointResult for FoundUserRank {
type RequestResult = SingleResponse;
type ErrorResult = data::ApiError;
fn from_raw(raw: SingleResponse) -> Result<FoundUserRank> {
let SingleResponse {
ok,
rank,
score,
season,
user,
} = raw;
if ok != 1 {
return Err(ApiError::NotOk(ok).into());
}
Ok(FoundUserRank {
season_id: season,
user_id: user,
rank: rank,
raw_score: score,
_non_exhaustive: (),
})
}
}
impl EndpointResult for Vec<FoundUserRank> {
type RequestResult = AllSeasonRanksResponse;
type ErrorResult = data::ApiError;
fn from_raw(raw: AllSeasonRanksResponse) -> Result<Vec<FoundUserRank>> {
let AllSeasonRanksResponse {
ok,
list: season_ranks,
} = raw;
if ok != 1 {
return Err(ApiError::NotOk(ok).into());
}
Ok(season_ranks
.into_iter()
.map(|raw_rank| {
let InnerAllSeasonsResponse {
rank,
score,
season,
user,
} = raw_rank;
FoundUserRank {
season_id: season,
user_id: user,
rank: rank,
raw_score: score,
_non_exhaustive: (),
}
})
.collect())
}
}
#[cfg(test)]
mod tests {
use super::FoundUserRank;
use crate::EndpointResult;
use serde_json;
fn test_parse_single(json: serde_json::Value) {
let response = serde_json::from_value(json).unwrap();
let _ = FoundUserRank::from_raw(response).unwrap();
}
fn test_parse_multi(json: serde_json::Value) {
let response = serde_json::from_value(json).unwrap();
let _ = Vec::<FoundUserRank>::from_raw(response).unwrap();
}
#[test]
fn parse_sample_single_season() {
test_parse_single(json! ({
"_id": "58b60f2f75a8e42a5c0923f9",
"ok": 1,
"rank": 68,
"score": 43146791,
"season": "2017-03",
"user": "57874d42d0ae911e3bd15bbc"
}));
}
#[test]
fn parse_sample_multiple_seasons() {
test_parse_multi(json! ({
"list": [
{
"_id": "578bec7c276fc5fcb7dfe0c1",
"rank": 1016,
"score": 1195020,
"season": "2016-07",
"user": "57874d42d0ae911e3bd15bbc"
},
{
"_id": "579e911a6cb50b7bd8f9d346",
"rank": 213,
"score": 17250219,
"season": "2016-08",
"user": "57874d42d0ae911e3bd15bbc"
},
{
"_id": "57c76f95dab8e790758fccb0",
"rank": 129,
"score": 38156711,
"season": "2016-09",
"user": "57874d42d0ae911e3bd15bbc"
},
{
"_id": "57eefc9577a8d271d10d9b54",
"rank": 110,
"score": 53901405,
"season": "2016-10",
"user": "57874d42d0ae911e3bd15bbc"
},
{
"_id": "5817db0fd22ddaa587ebfae0",
"rank": 47,
"score": 111031282,
"season": "2016-11",
"user": "57874d42d0ae911e3bd15bbc"
},
{
"_id": "583f682780bb5a3d2b36f1e8",
"rank": 60,
"score": 112480526,
"season": "2016-12",
"user": "57874d42d0ae911e3bd15bbc"
},
{
"_id": "586846a0ec0e632daa9077fe",
"rank": 76,
"score": 99291185,
"season": "2017-01",
"user": "57874d42d0ae911e3bd15bbc"
},
{
"_id": "589125339c76d517f2424990",
"rank": 59,
"score": 119478210,
"season": "2017-02",
"user": "57874d42d0ae911e3bd15bbc"
},
{
"_id": "58b60f2f75a8e42a5c0923f9",
"rank": 68,
"score": 43159803,
"season": "2017-03",
"user": "57874d42d0ae911e3bd15bbc"
}
],
"ok": 1
}));
}
}