rgc_chart/models/osu/
chart.rs1use std::fmt::{self, Display, Formatter};
2use crate::{models::{generic::sound::SoundBank, osu::*}, parsers::osu::from_osu};
3
4#[derive(Debug, Clone, PartialEq)]
5pub enum OsuMode {
6 Standard,
7 Taiko,
8 Catch,
9 Mania,
10 Unknown,
11}
12
13impl Display for OsuMode {
14 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
15 let mode_str = match self {
16 OsuMode::Standard => "osu!",
17 OsuMode::Taiko => "osu!taiko",
18 OsuMode::Catch => "osu!catch",
19 OsuMode::Mania => "osu!mania",
20 OsuMode::Unknown => "unknown",
21 };
22 write!(f, "{mode_str}")
23 }
24}
25
26pub struct OsuFile {
27 pub general: general::General,
28 pub editor: Option<editor::Editor>,
29 pub metadata: metadata::Metadata,
30 pub difficulty: difficulty::Difficulty,
31 pub events: events::Events,
32 pub timing_points: timing_points::TimingPoints,
33 pub hitobjects: hitobjects::HitObjects,
34}
35
36impl Default for OsuFile {
37 fn default() -> Self {
38 OsuFile {
39 general: Default::default(),
40 editor: None,
41 metadata: Default::default(),
42 difficulty: Default::default(),
43 events: Default::default(),
44 timing_points: Default::default(),
45 hitobjects: Default::default(),
46 }
47 }
48}
49
50impl OsuFile {
51 pub fn from_str(str: &str) -> Result<Self, Box<dyn std::error::Error>> {
52 from_osu(str)
53 }
54}
55
56impl OsuFile {
57 pub fn to_osu_format_taiko(&self) -> String {
58 let mut result = String::new();
59 result.push_str("osu file format v14\n\n");
60
61 result.push_str("[General]\n");
62 result.push_str(&self.general.to_osu_format());
63 result.push_str("\n\n");
64
65 if let Some(ref editor) = self.editor {
66 result.push_str("[Editor]\n");
67 result.push_str(&editor.to_osu_format());
68 result.push_str("\n\n");
69 }
70
71 result.push_str("[Metadata]\n");
72 result.push_str(&self.metadata.to_osu_format());
73 result.push_str("\n\n");
74
75 result.push_str("[Difficulty]\n");
76 result.push_str(&self.difficulty.to_osu_format());
77 result.push_str("\n\n");
78
79 result.push_str("[Events]\n");
80 result.push_str(&self.events.to_osu_format());
81 result.push_str("\n");
82
83 result.push_str("[TimingPoints]\n");
84 result.push_str(&self.timing_points.to_osu_format());
85 result.push_str("\n\n");
86
87 result.push_str("[HitObjects]\n");
88 result.push_str(&self.hitobjects.to_osu_format_taiko());
89
90 result
91 }
92
93 pub fn to_osu_format_catch(&self) -> String {
94 let mut result = String::new();
95 result.push_str("osu file format v14\n\n");
96
97 result.push_str("[General]\n");
98 result.push_str(&self.general.to_osu_format());
99 result.push_str("\n\n");
100
101 if let Some(ref editor) = self.editor {
102 result.push_str("[Editor]\n");
103 result.push_str(&editor.to_osu_format());
104 result.push_str("\n\n");
105 }
106
107 result.push_str("[Metadata]\n");
108 result.push_str(&self.metadata.to_osu_format());
109 result.push_str("\n\n");
110
111 result.push_str("[Difficulty]\n");
112 result.push_str(&self.difficulty.to_osu_format());
113 result.push_str("\n\n");
114
115 result.push_str("[Events]\n");
116 result.push_str(&self.events.to_osu_format());
117 result.push_str("\n");
118
119 result.push_str("[TimingPoints]\n");
120 result.push_str(&self.timing_points.to_osu_format());
121 result.push_str("\n\n");
122
123 result.push_str("[HitObjects]\n");
124 result.push_str(&self.hitobjects.to_osu_format_catch());
125
126 result
127 }
128
129 pub fn to_osu_format_mania(&self, soundbank: &mut SoundBank) -> String {
130 let mut result = String::new();
131 result.push_str("osu file format v14\n\n");
132
133 result.push_str("[General]\n");
134 result.push_str(&self.general.to_osu_format());
135 result.push_str("\n\n");
136
137 if let Some(ref editor) = self.editor {
138 result.push_str("[Editor]\n");
139 result.push_str(&editor.to_osu_format());
140 result.push_str("\n\n");
141 }
142
143 result.push_str("[Metadata]\n");
144 result.push_str(&self.metadata.to_osu_format());
145 result.push_str("\n\n");
146
147 result.push_str("[Difficulty]\n");
148 result.push_str(&self.difficulty.to_osu_format());
149 result.push_str("\n\n");
150
151 result.push_str("[Events]\n");
152 result.push_str(&self.events.to_osu_format());
153 result.push_str("\n");
154
155 result.push_str("[TimingPoints]\n");
156 result.push_str(&self.timing_points.to_osu_format());
157 result.push_str("\n\n");
158
159 result.push_str("[HitObjects]\n");
160 result.push_str(&self.hitobjects.to_osu_format_mania(soundbank));
161
162 result
163 }
164
165 pub fn to_osu_format_mania_no_soundbank(&self) -> String {
166 let mut result = String::new();
167 result.push_str("osu file format v14\n\n");
168
169 result.push_str("[General]\n");
170 result.push_str(&self.general.to_osu_format());
171 result.push_str("\n\n");
172
173 if let Some(ref editor) = self.editor {
174 result.push_str("[Editor]\n");
175 result.push_str(&editor.to_osu_format());
176 result.push_str("\n\n");
177 }
178
179 result.push_str("[Metadata]\n");
180 result.push_str(&self.metadata.to_osu_format());
181 result.push_str("\n\n");
182
183 result.push_str("[Difficulty]\n");
184 result.push_str(&self.difficulty.to_osu_format());
185 result.push_str("\n\n");
186
187 result.push_str("[Events]\n");
188 result.push_str(&self.events.to_osu_format());
189 result.push_str("\n");
190
191 result.push_str("[TimingPoints]\n");
192 result.push_str(&self.timing_points.to_osu_format());
193 result.push_str("\n\n");
194
195 result.push_str("[HitObjects]\n");
196 result.push_str(&self.hitobjects.to_osu_format_mania_no_soundbank());
197
198 result
199 }
200
201 pub fn to_osu_format_standard(&self) -> String {
202 self.to_osu_format()
203 }
204
205 pub fn to_osu_format(&self) -> String {
206 let mut result = String::new();
207 result.push_str("osu file format v14\n\n");
208
209 result.push_str("[General]\n");
210 result.push_str(&self.general.to_osu_format());
211 result.push_str("\n\n");
212
213 if let Some(ref editor) = self.editor {
214 result.push_str("[Editor]\n");
215 result.push_str(&editor.to_osu_format());
216 result.push_str("\n\n");
217 }
218
219 result.push_str("[Metadata]\n");
220 result.push_str(&self.metadata.to_osu_format());
221 result.push_str("\n\n");
222
223 result.push_str("[Difficulty]\n");
224 result.push_str(&self.difficulty.to_osu_format());
225 result.push_str("\n\n");
226
227 result.push_str("[Events]\n");
228 result.push_str(&self.events.to_osu_format());
229 result.push_str("\n");
230
231 result.push_str("[TimingPoints]\n");
232 result.push_str(&self.timing_points.to_osu_format());
233 result.push_str("\n\n");
234
235 result.push_str("[HitObjects]\n");
236 result.push_str(&self.hitobjects.to_osu_format());
237
238 result
239 }
240}