Skip to main content

rosu_pp/any/difficulty/
inspect.rs

1use crate::{
2    Difficulty,
3    model::{beatmap::BeatmapAttribute, mods::GameMods},
4};
5
6/// [`Difficulty`] but all fields are public for inspection.
7#[derive(Clone, Debug, Default, PartialEq)]
8pub struct InspectDifficulty {
9    /// Specify mods.
10    pub mods: GameMods,
11    /// Amount of passed objects for partial plays, e.g. a fail.
12    pub passed_objects: Option<u32>,
13    /// Adjust the clock rate used in the calculation.
14    pub clock_rate: Option<f64>,
15    /// Override a beatmap's set AR.
16    ///
17    /// Only relevant for osu! and osu!catch.
18    pub ar: BeatmapAttribute,
19    /// Override a beatmap's set CS.
20    ///
21    /// Only relevant for osu! and osu!catch.
22    pub cs: BeatmapAttribute,
23    /// Override a beatmap's set HP.
24    pub hp: BeatmapAttribute,
25    /// Override a beatmap's set OD.
26    pub od: BeatmapAttribute,
27    /// Adjust patterns as if the HR mod is enabled.
28    ///
29    /// Only relevant for osu!catch.
30    pub hardrock_offsets: Option<bool>,
31    /// Whether the calculated attributes belong to an osu!lazer or osu!stable
32    /// score.
33    ///
34    /// Defaults to `true`.
35    pub lazer: Option<bool>,
36}
37
38impl InspectDifficulty {
39    /// Convert `self` into a [`Difficulty`].
40    pub fn into_difficulty(self) -> Difficulty {
41        let Self {
42            mods,
43            passed_objects,
44            clock_rate,
45            ar,
46            cs,
47            hp,
48            od,
49            hardrock_offsets,
50            lazer,
51        } = self;
52
53        let mut difficulty = Difficulty::new().mods(mods);
54
55        if let Some(passed_objects) = passed_objects {
56            difficulty = difficulty.passed_objects(passed_objects);
57        }
58
59        if let Some(clock_rate) = clock_rate {
60            difficulty = difficulty.clock_rate(clock_rate);
61        }
62
63        macro_rules! set_attr {
64            ( $attr:ident ) => {
65                match $attr {
66                    BeatmapAttribute::None | BeatmapAttribute::Value(_) => {}
67                    BeatmapAttribute::Given(value) => difficulty = difficulty.$attr(value, false),
68                    BeatmapAttribute::Fixed(value) => difficulty = difficulty.$attr(value, true),
69                };
70            };
71        }
72
73        set_attr!(ar);
74        set_attr!(cs);
75        set_attr!(hp);
76        set_attr!(od);
77
78        if let Some(hardrock_offsets) = hardrock_offsets {
79            difficulty = difficulty.hardrock_offsets(hardrock_offsets);
80        }
81
82        if let Some(lazer) = lazer {
83            difficulty = difficulty.lazer(lazer);
84        }
85
86        difficulty
87    }
88}
89
90impl From<InspectDifficulty> for Difficulty {
91    fn from(difficulty: InspectDifficulty) -> Self {
92        difficulty.into_difficulty()
93    }
94}
95
96impl From<Difficulty> for InspectDifficulty {
97    fn from(difficulty: Difficulty) -> Self {
98        difficulty.inspect()
99    }
100}