2020-02-01 21:35:37 +00:00
|
|
|
//! Utilities for working with ranks, represented as `(Tier, Division)` tuples.
|
|
|
|
|
|
|
|
use std::iter::Peekable;
|
|
|
|
|
|
|
|
use strum::IntoEnumIterator;
|
|
|
|
|
|
|
|
use super::{ Tier, Division };
|
|
|
|
|
2020-06-02 19:45:40 +00:00
|
|
|
/// (Tier, Division) tuple representing a rank.
|
|
|
|
pub type Rank = ( Tier, Division );
|
|
|
|
|
2020-02-01 21:35:37 +00:00
|
|
|
/// Iterator for iterating `(Tier, Division)` rank tuples.
|
|
|
|
pub struct Iter {
|
|
|
|
tier_iter: Peekable<<Tier as IntoEnumIterator>::Iterator>,
|
|
|
|
div_iter: <Division as IntoEnumIterator>::Iterator,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Iterator for Iter {
|
2020-06-02 19:45:40 +00:00
|
|
|
type Item = Rank;
|
2020-02-01 21:35:37 +00:00
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
// First find the tier (innermost loop).
|
|
|
|
// If none found, we go to next tier (in unwrap_or_else case).
|
2020-06-02 19:45:40 +00:00
|
|
|
let div = self.div_iter.next()
|
2020-02-01 21:35:37 +00:00
|
|
|
.unwrap_or_else(|| {
|
|
|
|
// If no divisions available, go to next tier, reset the divisions, and return I.
|
|
|
|
self.tier_iter.next();
|
|
|
|
self.div_iter = Division::iter();
|
|
|
|
self.div_iter.next().unwrap()
|
|
|
|
});
|
2021-05-22 04:25:19 +00:00
|
|
|
|
2020-02-01 21:35:37 +00:00
|
|
|
// Then find the tier.
|
|
|
|
let tier = *self.tier_iter.peek()?;
|
|
|
|
// If its an apex tier go to next tier and reset the divisions.
|
|
|
|
if tier.is_apex() {
|
|
|
|
self.tier_iter.next();
|
|
|
|
self.div_iter = Division::iter();
|
|
|
|
}
|
|
|
|
|
2020-06-02 19:45:40 +00:00
|
|
|
Some(( tier, div ))
|
2020-02-01 21:35:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns an iterator over all `(Tier, Division)` pairs, ordered from highest rank to lowest rank.
|
|
|
|
///
|
|
|
|
/// Apex tiers are all division I, for example: `(Tier::CHALLENGER, Division::I)`.
|
|
|
|
/// This matches how they are represented by Riot. There is no "Challenger II", etc.
|
|
|
|
pub fn iter() -> Iter {
|
|
|
|
Iter {
|
|
|
|
tier_iter: Tier::iter().peekable(),
|
|
|
|
div_iter: Division::iter(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns an iterator over all `(Tier, Division)` pairs, excluding apex (Master+) tiers,
|
|
|
|
/// ordered from highest (Diamond I) to lowest (Iron IV).
|
|
|
|
pub fn non_apex_iter() -> Iter {
|
|
|
|
let mut tier_iter = Tier::iter().peekable();
|
|
|
|
while tier_iter.peek().unwrap().is_apex() {
|
|
|
|
tier_iter.next();
|
|
|
|
}
|
|
|
|
Iter {
|
2021-10-30 05:38:48 +00:00
|
|
|
tier_iter,
|
2020-02-01 21:35:37 +00:00
|
|
|
div_iter: Division::iter(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::{ Tier, Division };
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn iter() {
|
|
|
|
let mut it = super::iter();
|
2020-06-02 19:45:40 +00:00
|
|
|
assert_eq!(Some(( Tier::CHALLENGER, 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::DIAMOND, Division::I )), it.next());
|
|
|
|
assert_eq!(Some(( Tier::DIAMOND, Division::II )), it.next());
|
2020-02-01 21:35:37 +00:00
|
|
|
let mut last = None;
|
|
|
|
for next in &mut it {
|
|
|
|
last = Some(next);
|
|
|
|
}
|
2020-06-02 19:45:40 +00:00
|
|
|
assert_eq!(Some(( Tier::IRON, Division::IV )), last);
|
2020-02-01 21:35:37 +00:00
|
|
|
assert_eq!(None, it.next());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn non_apex_iter() {
|
|
|
|
let mut it = super::non_apex_iter();
|
|
|
|
assert_eq!(Some((Tier::DIAMOND, Division::I)), it.next());
|
|
|
|
assert_eq!(Some((Tier::DIAMOND, Division::II)), it.next());
|
|
|
|
assert_eq!(Some((Tier::DIAMOND, Division::III)), it.next());
|
|
|
|
assert_eq!(Some((Tier::DIAMOND, Division::IV)), it.next());
|
|
|
|
assert_eq!(Some((Tier::PLATINUM, Division::I)), it.next());
|
|
|
|
let mut last = None;
|
|
|
|
for next in &mut it {
|
|
|
|
last = Some(next);
|
|
|
|
}
|
|
|
|
assert_eq!(Some((Tier::IRON, Division::IV)), last);
|
|
|
|
assert_eq!(None, it.next());
|
|
|
|
}
|
|
|
|
}
|