rosu_pp/any/difficulty/
gradual.rs1use rosu_map::section::general::GameMode;
2
3use crate::{
4 Beatmap, Difficulty,
5 any::DifficultyAttributes,
6 catch::{Catch, CatchGradualDifficulty},
7 mania::{Mania, ManiaGradualDifficulty},
8 model::{
9 beatmap::TooSuspicious,
10 mode::{ConvertError, IGameMode},
11 },
12 osu::{Osu, OsuGradualDifficulty},
13 taiko::{Taiko, TaikoGradualDifficulty},
14};
15
16pub enum GradualDifficulty {
46 Osu(OsuGradualDifficulty),
47 Taiko(TaikoGradualDifficulty),
48 Catch(CatchGradualDifficulty),
49 Mania(ManiaGradualDifficulty),
50}
51
52impl GradualDifficulty {
53 #[expect(clippy::missing_panics_doc, reason = "unreachable")]
55 pub fn new(difficulty: Difficulty, map: &Beatmap) -> Self {
56 Self::new_with_mode(difficulty, map, map.mode).expect("no conversion required")
57 }
58
59 pub fn checked_new(difficulty: Difficulty, map: &Beatmap) -> Result<Self, TooSuspicious> {
62 map.check_suspicion()?;
65
66 Ok(Self::new(difficulty, map))
67 }
68
69 pub fn new_with_mode(
72 difficulty: Difficulty,
73 map: &Beatmap,
74 mode: GameMode,
75 ) -> Result<Self, ConvertError> {
76 match mode {
77 GameMode::Osu => Osu::gradual_difficulty(difficulty, map).map(Self::Osu),
78 GameMode::Taiko => Taiko::gradual_difficulty(difficulty, map).map(Self::Taiko),
79 GameMode::Catch => Catch::gradual_difficulty(difficulty, map).map(Self::Catch),
80 GameMode::Mania => Mania::gradual_difficulty(difficulty, map).map(Self::Mania),
81 }
82 }
83}
84
85impl Iterator for GradualDifficulty {
86 type Item = DifficultyAttributes;
87
88 fn next(&mut self) -> Option<Self::Item> {
89 match self {
90 GradualDifficulty::Osu(gradual) => gradual.next().map(DifficultyAttributes::Osu),
91 GradualDifficulty::Taiko(gradual) => gradual.next().map(DifficultyAttributes::Taiko),
92 GradualDifficulty::Catch(gradual) => gradual.next().map(DifficultyAttributes::Catch),
93 GradualDifficulty::Mania(gradual) => gradual.next().map(DifficultyAttributes::Mania),
94 }
95 }
96
97 fn size_hint(&self) -> (usize, Option<usize>) {
98 match self {
99 GradualDifficulty::Osu(gradual) => gradual.size_hint(),
100 GradualDifficulty::Taiko(gradual) => gradual.size_hint(),
101 GradualDifficulty::Catch(gradual) => gradual.size_hint(),
102 GradualDifficulty::Mania(gradual) => gradual.size_hint(),
103 }
104 }
105
106 fn nth(&mut self, n: usize) -> Option<Self::Item> {
107 match self {
108 GradualDifficulty::Osu(gradual) => gradual.nth(n).map(DifficultyAttributes::Osu),
109 GradualDifficulty::Taiko(gradual) => gradual.nth(n).map(DifficultyAttributes::Taiko),
110 GradualDifficulty::Catch(gradual) => gradual.nth(n).map(DifficultyAttributes::Catch),
111 GradualDifficulty::Mania(gradual) => gradual.nth(n).map(DifficultyAttributes::Mania),
112 }
113 }
114}
115
116impl ExactSizeIterator for GradualDifficulty {
117 fn len(&self) -> usize {
118 match self {
119 GradualDifficulty::Osu(gradual) => gradual.len(),
120 GradualDifficulty::Taiko(gradual) => gradual.len(),
121 GradualDifficulty::Catch(gradual) => gradual.len(),
122 GradualDifficulty::Mania(gradual) => gradual.len(),
123 }
124 }
125}