mirror of
https://github.com/MingweiSamuel/Riven.git
synced 2024-12-27 03:16:33 +00:00
Add UNRANKED to tier enum, fix #11
This commit is contained in:
parent
2f1698b183
commit
ae6056569e
3 changed files with 121 additions and 20 deletions
|
@ -1,8 +1,8 @@
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
use num_enum::{ IntoPrimitive, TryFromPrimitive };
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr };
|
use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr };
|
||||||
use num_enum::{ IntoPrimitive, TryFromPrimitive };
|
|
||||||
|
|
||||||
/// LoL and TFT rank divisions, I, II, III, IV, and (deprecated) V.
|
/// LoL and TFT rank divisions, I, II, III, IV, and (deprecated) V.
|
||||||
///
|
///
|
||||||
|
@ -31,9 +31,9 @@ serde_string!(Division);
|
||||||
/// Ordered from high rank (I) to low (IV).
|
/// Ordered from high rank (I) to low (IV).
|
||||||
/// Excludes V, which is deprecated.
|
/// Excludes V, which is deprecated.
|
||||||
impl IntoEnumIterator for Division {
|
impl IntoEnumIterator for Division {
|
||||||
type Iterator = std::slice::Iter<'static, Self>;
|
type Iterator = std::iter::Copied<std::slice::Iter<'static, Self>>;
|
||||||
fn iter() -> Self::Iterator {
|
fn iter() -> Self::Iterator {
|
||||||
[ Self::I, Self::II, Self::III, Self::IV ].iter()
|
[ Self::I, Self::II, Self::III, Self::IV ].iter().copied()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,9 @@ use strum::IntoEnumIterator;
|
||||||
|
|
||||||
use super::{ Tier, Division };
|
use super::{ Tier, Division };
|
||||||
|
|
||||||
|
/// (Tier, Division) tuple representing a rank.
|
||||||
|
pub type Rank = ( Tier, Division );
|
||||||
|
|
||||||
/// Iterator for iterating `(Tier, Division)` rank tuples.
|
/// Iterator for iterating `(Tier, Division)` rank tuples.
|
||||||
pub struct Iter {
|
pub struct Iter {
|
||||||
tier_iter: Peekable<<Tier as IntoEnumIterator>::Iterator>,
|
tier_iter: Peekable<<Tier as IntoEnumIterator>::Iterator>,
|
||||||
|
@ -13,11 +16,11 @@ pub struct Iter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for Iter {
|
impl Iterator for Iter {
|
||||||
type Item = (Tier, Division);
|
type Item = Rank;
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
// First find the tier (innermost loop).
|
// First find the tier (innermost loop).
|
||||||
// If none found, we go to next tier (in unwrap_or_else case).
|
// If none found, we go to next tier (in unwrap_or_else case).
|
||||||
let div = *self.div_iter.next()
|
let div = self.div_iter.next()
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
// If no divisions available, go to next tier, reset the divisions, and return I.
|
// If no divisions available, go to next tier, reset the divisions, and return I.
|
||||||
self.tier_iter.next();
|
self.tier_iter.next();
|
||||||
|
@ -33,7 +36,7 @@ impl Iterator for Iter {
|
||||||
self.div_iter = Division::iter();
|
self.div_iter = Division::iter();
|
||||||
}
|
}
|
||||||
|
|
||||||
Some((tier, div))
|
Some(( tier, div ))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,16 +71,16 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn iter() {
|
fn iter() {
|
||||||
let mut it = super::iter();
|
let mut it = super::iter();
|
||||||
assert_eq!(Some((Tier::CHALLENGER, Division::I)), it.next());
|
assert_eq!(Some(( Tier::CHALLENGER, Division::I )), it.next());
|
||||||
assert_eq!(Some((Tier::GRANDMASTER, Division::I)), it.next());
|
assert_eq!(Some(( Tier::GRANDMASTER, Division::I )), it.next());
|
||||||
assert_eq!(Some((Tier::MASTER, Division::I)), it.next());
|
assert_eq!(Some(( Tier::MASTER, Division::I )), it.next());
|
||||||
assert_eq!(Some((Tier::DIAMOND, Division::I)), it.next());
|
assert_eq!(Some(( Tier::DIAMOND, Division::I )), it.next());
|
||||||
assert_eq!(Some((Tier::DIAMOND, Division::II)), it.next());
|
assert_eq!(Some(( Tier::DIAMOND, Division::II )), it.next());
|
||||||
let mut last = None;
|
let mut last = None;
|
||||||
for next in &mut it {
|
for next in &mut it {
|
||||||
last = Some(next);
|
last = Some(next);
|
||||||
}
|
}
|
||||||
assert_eq!(Some((Tier::IRON, Division::IV)), last);
|
assert_eq!(Some(( Tier::IRON, Division::IV )), last);
|
||||||
assert_eq!(None, it.next());
|
assert_eq!(None, it.next());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
use num_enum::{ IntoPrimitive, TryFromPrimitive };
|
use num_enum::{ IntoPrimitive, TryFromPrimitive };
|
||||||
use strum_macros::{ EnumString, EnumIter, Display, AsRefStr, IntoStaticStr };
|
use strum_macros::{ EnumString, Display, AsRefStr, IntoStaticStr };
|
||||||
|
|
||||||
/// LoL and TFT ranked tiers, such as gold, diamond, challenger, etc.
|
/// LoL and TFT ranked tiers, such as gold, diamond, challenger, etc.
|
||||||
///
|
///
|
||||||
|
@ -11,7 +12,7 @@ use strum_macros::{ EnumString, EnumIter, Display, AsRefStr, IntoStaticStr };
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[derive(Eq, PartialEq, Hash, PartialOrd, Ord)]
|
#[derive(Eq, PartialEq, Hash, PartialOrd, Ord)]
|
||||||
#[derive(IntoPrimitive, TryFromPrimitive)]
|
#[derive(IntoPrimitive, TryFromPrimitive)]
|
||||||
#[derive(EnumString, EnumIter, Display, AsRefStr, IntoStaticStr)]
|
#[derive(EnumString, Display, AsRefStr, IntoStaticStr)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum Tier {
|
pub enum Tier {
|
||||||
/// Challenger, the highest tier, an apex tier. Repr: `220_u8`.
|
/// Challenger, the highest tier, an apex tier. Repr: `220_u8`.
|
||||||
|
@ -32,19 +33,64 @@ pub enum Tier {
|
||||||
BRONZE = 60,
|
BRONZE = 60,
|
||||||
/// Iron, the lowest tier. Repr: `40_u8`.
|
/// Iron, the lowest tier. Repr: `40_u8`.
|
||||||
IRON = 40,
|
IRON = 40,
|
||||||
|
|
||||||
|
/// Unranked, no tier. Repr: `0_u8`.
|
||||||
|
UNRANKED = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
serde_string!(Tier);
|
serde_string!(Tier);
|
||||||
|
|
||||||
impl Tier {
|
impl Tier {
|
||||||
/// If this tier is an apex tier: master and above.
|
/// If this tier is an apex tier: master, grandmaster, or challenger.
|
||||||
///
|
/// Returns false for unranked.
|
||||||
/// Inverse of is_standard().
|
|
||||||
///
|
///
|
||||||
/// These tiers are NOT queryable by LeagueV4Endpoints::get_league_entries(...).
|
/// These tiers are NOT queryable by LeagueV4Endpoints::get_league_entries(...).
|
||||||
pub const fn is_apex(self) -> bool {
|
pub const fn is_apex(self) -> bool {
|
||||||
|
// Casts needed for const.
|
||||||
(Self::MASTER as u8) <= (self as u8)
|
(Self::MASTER as u8) <= (self as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If this tier is a "standard" tier: iron through diamond.
|
||||||
|
/// Returns false for unranked.
|
||||||
|
///
|
||||||
|
/// ONLY these tiers are queryable by LeagueV4Endpoints::get_league_entries(...).
|
||||||
|
pub fn is_standard(self) -> bool {
|
||||||
|
// Casts needed for const.
|
||||||
|
((Self::UNRANKED as u8) < (self as u8)) && ((self as u8) < (Self::MASTER as u8))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If this tier is ranked. Returns true for iron through challenger, false for unranked.
|
||||||
|
pub const fn is_ranked(self) -> bool {
|
||||||
|
// Casts needed for const.
|
||||||
|
(Self::UNRANKED as u8) < (self as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If this tier is unranked (`Tier::UNRANKED`).
|
||||||
|
///
|
||||||
|
/// UNRANKED is returned by `Participant.highest_achieved_season_tier`.
|
||||||
|
pub const fn is_unranked(self) -> bool {
|
||||||
|
// Casts needed for const.
|
||||||
|
(self as u8) <= (Self::UNRANKED as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts UNRANKED to None and all ranked tiers to Some(...).
|
||||||
|
pub fn to_ranked(self) -> Option<Self> {
|
||||||
|
if self.is_unranked() { None } else { Some(self) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a DoubleEndedIterator of I, II, III, IV.
|
||||||
|
/// Ordered from high rank (I) to low (IV).
|
||||||
|
/// Excludes V, which is deprecated.
|
||||||
|
impl IntoEnumIterator for Tier {
|
||||||
|
type Iterator = std::iter::Copied<std::slice::Iter<'static, Self>>;
|
||||||
|
fn iter() -> Self::Iterator {
|
||||||
|
[
|
||||||
|
Self::CHALLENGER, Self::GRANDMASTER, Self::MASTER,
|
||||||
|
Self::DIAMOND, Self::PLATINUM, Self::GOLD,
|
||||||
|
Self::SILVER, Self::BRONZE, Self::IRON
|
||||||
|
].iter().copied()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -52,30 +98,64 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sort() {
|
fn ord() {
|
||||||
assert!(Tier::GOLD < Tier::DIAMOND);
|
assert!(Tier::GOLD < Tier::DIAMOND);
|
||||||
|
assert!(Tier::UNRANKED < Tier::IRON);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn apex_check() {
|
fn is_apex() {
|
||||||
assert!( Tier::GRANDMASTER.is_apex());
|
assert!(Tier::GRANDMASTER.is_apex());
|
||||||
assert!(!Tier::DIAMOND.is_apex());
|
assert!(!Tier::DIAMOND.is_apex());
|
||||||
|
assert!(!Tier::UNRANKED.is_apex());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn is_ranked() {
|
||||||
|
assert!(Tier::GRANDMASTER.is_ranked());
|
||||||
|
assert!(Tier::DIAMOND.is_ranked());
|
||||||
|
assert!(!Tier::UNRANKED.is_ranked());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn is_unranked() {
|
||||||
|
assert!(!Tier::GRANDMASTER.is_unranked());
|
||||||
|
assert!(!Tier::DIAMOND.is_unranked());
|
||||||
|
assert!(Tier::UNRANKED.is_unranked());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn to_ranked() {
|
||||||
|
assert_eq!(Some(Tier::GRANDMASTER), Tier::GRANDMASTER.to_ranked());
|
||||||
|
assert_eq!(Some(Tier::DIAMOND), Tier::DIAMOND.to_ranked());
|
||||||
|
assert_eq!(None, Tier::UNRANKED.to_ranked());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn is_standard() {
|
||||||
|
assert!(!Tier::GRANDMASTER.is_standard());
|
||||||
|
assert!(Tier::DIAMOND.is_standard());
|
||||||
|
assert!(!Tier::UNRANKED.is_standard());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn to_string() {
|
fn to_string() {
|
||||||
assert_eq!("GRANDMASTER", Tier::GRANDMASTER.as_ref());
|
assert_eq!("GRANDMASTER", Tier::GRANDMASTER.as_ref());
|
||||||
assert_eq!("GRANDMASTER", Tier::GRANDMASTER.to_string());
|
assert_eq!("GRANDMASTER", Tier::GRANDMASTER.to_string());
|
||||||
|
assert_eq!("UNRANKED", Tier::UNRANKED.as_ref());
|
||||||
|
assert_eq!("UNRANKED", Tier::UNRANKED.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_string() {
|
fn from_string() {
|
||||||
assert_eq!(Ok(Tier::GRANDMASTER), "GRANDMASTER".parse());
|
assert_eq!(Ok(Tier::GRANDMASTER), "GRANDMASTER".parse());
|
||||||
|
assert_eq!(Ok(Tier::UNRANKED), "UNRANKED".parse());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn iter() {
|
fn iter() {
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
let mut iter = Tier::iter();
|
let mut iter = Tier::iter();
|
||||||
assert_eq!(Some(Tier::CHALLENGER), iter.next());
|
assert_eq!(Some(Tier::CHALLENGER), iter.next());
|
||||||
iter.next();
|
iter.next();
|
||||||
|
@ -87,5 +167,23 @@ mod tests {
|
||||||
iter.next();
|
iter.next();
|
||||||
assert_eq!(Some(Tier::IRON), iter.next());
|
assert_eq!(Some(Tier::IRON), iter.next());
|
||||||
assert_eq!(None, iter.next());
|
assert_eq!(None, iter.next());
|
||||||
|
assert_eq!(None, iter.next_back());
|
||||||
|
|
||||||
|
let mut iter = Tier::iter().rev();
|
||||||
|
assert_eq!(Some(Tier::IRON), iter.next());
|
||||||
|
iter.next();
|
||||||
|
iter.next();
|
||||||
|
iter.next();
|
||||||
|
iter.next();
|
||||||
|
assert_eq!(Some(Tier::DIAMOND), iter.next());
|
||||||
|
iter.next();
|
||||||
|
iter.next();
|
||||||
|
assert_eq!(Some(Tier::CHALLENGER), iter.next());
|
||||||
|
assert_eq!(None, iter.next());
|
||||||
|
assert_eq!(None, iter.next_back());
|
||||||
|
|
||||||
|
let mut iter = Tier::iter();
|
||||||
|
assert_eq!(Some(Tier::CHALLENGER), iter.next());
|
||||||
|
assert_eq!(Some(Tier::IRON), iter.next_back());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue