1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
//! A library to provide types for all [osu!] gamemods as defined in the official [mods.json] file.
//!
//! Individual gamemod types are generated automatically through the [`generate-mods`] binary.
//!
//! ## Types
//!
//! In total, there are four different ways of handling mods.
//!
//! ### `GameModsLegacy`
//!
//! [`GameModsLegacy`] is a lightweight type that is essentially just bitflags for the [legacy mods].
//!
//! ```
//! use rosu_mods::GameModsLegacy;
//!
//! let hdnc = GameModsLegacy::Nightcore | GameModsLegacy::Hidden;
//! assert_eq!(hdnc.to_string(), "HDNC");
//! assert!(hdnc.contains(GameModsLegacy::DoubleTime));
//! ```
//!
//! ### `GameMods`
//!
//! [`GameMods`] is a collection of the [`GameMod`] enum. [`GameMod`] distinguishes between each
//! mode so if a mod is valid for multiple modes, each of those modes will have a variant for that
//! mod.
//!
//! ```
//! use rosu_mods::{GameMod, GameMods, generated_mods::AccuracyChallengeMania};
//!
//! # let mut mods = GameMods::new();
//! # mods.insert(GameMod::HardRockTaiko(Default::default()));
//! # mods.insert(GameMod::AccuracyChallengeTaiko(Default::default()));
//! # /*
//! // The `mods!` macro is only available if the `macros` feature is enabled
//! let mut mods: GameMods = rosu_mods::mods!(Taiko: AC HR);
//! # */
//!
//! // In addition to the two taiko mods, let's add a mania mod too
//! mods.insert(GameMod::AccuracyChallengeMania(AccuracyChallengeMania {
//! restart: Some(true),
//! ..Default::default()
//! }));
//!
//! assert_eq!(mods.to_string(), "ACHRAC");
//!
//! let mut iter = mods.into_iter();
//! assert_eq!(iter.next(), Some(GameMod::AccuracyChallengeTaiko(Default::default())));
//! assert_eq!(iter.next(), Some(GameMod::HardRockTaiko(Default::default())));
//! assert_eq!(iter.next(), Some(GameMod::AccuracyChallengeMania(AccuracyChallengeMania {
//! restart: Some(true),
//! minimum_accuracy: None,
//! accuracy_judge_mode: None,
//! })));
//! assert_eq!(iter.next(), None);
//! ```
//!
//! ### `GameModsIntermode`
//!
//! [`GameModsIntermode`] is a collection of the [`GameModIntermode`] enum. Unlike [`GameMod`],
//! this enum does not distinguish between modes. As such, variants do not carry further data
//! because a mod may have different settings depending on the mode.
//!
//! Since [`GameModsIntermode`] does not carry additional data and also consists of fewer variants,
//! it is generally easier to deal with than [`GameMods`].
//!
//! ```
//! use rosu_mods::{GameModIntermode, GameModsIntermode};
//!
//! # let mut mods = GameModsIntermode::new();
//! # mods.insert(GameModIntermode::Wiggle);
//! # mods.insert(GameModIntermode::FadeIn);
//! # /*
//! // The `mods!` macro is only available if the `macros` feature is enabled
//! let mut mods: GameModsIntermode = rosu_mods::mods!(WG FI);
//! # */
//!
//! // Let's add some more mods
//! mods.extend([GameModIntermode::Easy, GameModIntermode::HardRock]);
//!
//! assert_eq!(mods.to_string(), "EZFIHRWG");
//!
//! let mut iter = mods.into_iter();
//! assert_eq!(iter.next(), Some(GameModIntermode::Easy));
//! assert_eq!(iter.next(), Some(GameModIntermode::FadeIn));
//! assert_eq!(iter.next(), Some(GameModIntermode::HardRock));
//! assert_eq!(iter.next(), Some(GameModIntermode::Wiggle));
//! assert_eq!(iter.next(), None);
//! ```
//!
//! ### `GameModSimple`
//!
//! Unlike the other three, [`GameModSimple`] is not a collection but just a
//! single mod. Instead of providing types for each mod, it keeps things simple
//! and stores all settings into a plain `HashMap`.
//!
//! ```
//! use rosu_mods::{GameMod, GameModSimple, SettingSimple, generated_mods::AccuracyChallengeMania};
//!
//! let gamemod = GameMod::AccuracyChallengeMania(AccuracyChallengeMania {
//! restart: Some(true),
//! ..Default::default()
//! });
//! let simple = gamemod.into_simple();
//! assert_eq!(simple.settings.get("restart"), Some(&SettingSimple::Bool(true)));
//! ```
//!
//! ## Features
//!
//! | Flag | Description | Dependencies
//! | --------- | ------------------------------------------------------------------------------------------------ | ------------
//! | `default` | No features enabled |
//! | `macros` | Enables the `mods!` macro | [`pastey`]
//! | `serde` | Implements `serde::{Deserialize, Serialize}` for all types and enables the `serde` module | [`serde`]
//! | `rkyv` | Implements `rkyv::{Archive, Serialize, Deserialize}` for all types and enables the `rkyv` module | [`rkyv`]
//!
//! [osu!]: https://osu.ppy.sh/home
//! [mods.json]: https://github.com/ppy/osu-web/blob/master/database/mods.json
//! [`generate-mods`]: https://github.com/MaxOhn/rosu-mods/tree/main/generate-mods
//! [legacy mods]: https://github.com/ppy/osu-api/wiki#reference
//! [`pastey`]: https://docs.rs/pastey
//! [`serde`]: https://docs.rs/serde
//! [`rkyv`]: https://docs.rs/rkyv
//! [`GameModsLegacy`]: crate::legacy::GameModsLegacy
//! [`GameMods`]: crate::mods::GameMods
//! [`GameMod`]: crate::generated_mods::gamemod::GameMod
//! [`GameModsIntermode`]: crate::intermode::GameModsIntermode
//! [`GameModIntermode`]: crate::generated_mods::intermode::GameModIntermode
//! [`GameModSimple`]: crate::simple::GameModSimple
extern crate pastey;
/// Error types
/// Types to calculate intersecting mods.
/// Iterator types for mods.
pub use rkyv;
/// Types for (de)serialization through `serde`.
pub use ;
pub use ;
pub use GameModSimpleConversionError;