1
0
Fork 1
mirror of https://github.com/MingweiSamuel/Riven.git synced 2025-03-23 15:13:15 -07:00
Riven/riven/src/consts/tier.rs
2023-07-21 08:45:13 -07:00

221 lines
6.2 KiB
Rust

use num_enum::{IntoPrimitive, TryFromPrimitive};
use serde::{Deserialize, Serialize};
use strum::IntoEnumIterator;
use strum_macros::{AsRefStr, Display, EnumString, IntoStaticStr};
/// LoL and TFT ranked tiers, such as gold, diamond, challenger, etc.
///
/// Sorts from lowest rank to highest rank.
///
/// Repr'd as arbitrary `u8` values.
///
/// Implements [IntoEnumIterator](super::IntoEnumIterator).
#[derive(
Debug,
Copy,
Clone,
Eq,
PartialEq,
Hash,
PartialOrd,
Ord,
IntoPrimitive,
TryFromPrimitive,
EnumString,
Display,
AsRefStr,
IntoStaticStr,
Serialize,
Deserialize,
)]
#[repr(u8)]
pub enum Tier {
/// Challenger, the highest tier, an apex tier. Repr: `220_u8`.
CHALLENGER = 220,
/// Grand Master, an apex tier. Repr: `200_u8`.
GRANDMASTER = 200,
/// Master, an apex tier. Repr: `180_u8`.
MASTER = 180,
/// Diamond, the higest non-apex tier. Repr: `140_u8`.
DIAMOND = 140,
/// Emerald. Added in 2023. Repr: `130_u8`.
EMERALD = 130,
/// Platinum. Repr: `120_u8`.
PLATINUM = 120,
/// Gold. Repr: `100_u8`.
GOLD = 100,
/// Silver. Repr: `80_u8`.
SILVER = 80,
/// Bronze. Repr: `60_u8`.
BRONZE = 60,
/// Iron, the lowest tier. Repr: `40_u8`.
IRON = 40,
/// Unranked, no tier. Repr: `0_u8`.
/// Also deserializes from "NONE" returned by `lol-challenges-v1.getChallengePercentiles`.
#[serde(alias = "NONE")]
UNRANKED = 0,
}
impl Tier {
/// If this tier is an apex tier: [`Self::MASTER`], [`Self::GRANDMASTER`],
/// or [`Self::CHALLENGER`]. Returns false for [`Self::UNRANKED`].
///
/// These tiers are NOT queryable by LeagueV4Endpoints::get_league_entries(...).
pub const fn is_apex(self) -> bool {
// Casts needed for const.
(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 [`LeagueV4::get_league_entries(...)`](crate::endpoints::LeagueV4::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::EMERALD,
Self::PLATINUM,
Self::GOLD,
Self::SILVER,
Self::BRONZE,
Self::IRON,
]
.iter()
.copied()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ord() {
assert!(Tier::GOLD < Tier::DIAMOND);
assert!(Tier::UNRANKED < Tier::IRON);
}
#[test]
fn is_apex() {
assert!(Tier::GRANDMASTER.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]
fn to_string() {
assert_eq!("GRANDMASTER", Tier::GRANDMASTER.as_ref());
assert_eq!("GRANDMASTER", Tier::GRANDMASTER.to_string());
assert_eq!("UNRANKED", Tier::UNRANKED.as_ref());
assert_eq!("UNRANKED", Tier::UNRANKED.to_string());
}
#[test]
fn from_string() {
assert_eq!(Ok(Tier::GRANDMASTER), "GRANDMASTER".parse());
assert_eq!(Ok(Tier::UNRANKED), "UNRANKED".parse());
}
#[test]
fn iter() {
use strum::IntoEnumIterator;
let mut iter = Tier::iter();
assert_eq!(Some(Tier::CHALLENGER), iter.next());
iter.next();
iter.next();
assert_eq!(Some(Tier::DIAMOND), iter.next());
assert_eq!(Some(Tier::EMERALD), iter.next());
iter.next();
iter.next();
iter.next();
iter.next();
assert_eq!(Some(Tier::IRON), 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::EMERALD), 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());
}
}