Skip to main content

rgc_chart/models/osu/
chart.rs

1use 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}