1use serde::{Deserialize, Serialize};
2
3impl std::str::FromStr for Bmson {
4 type Err = serde_json::Error;
5 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
6 serde_json::from_str(s)
7 }
8}
9impl Bmson {
10 pub fn parse(source: &str) -> serde_json::Result<Bmson> {
12 serde_json::from_str(source)
13 }
14 pub fn to_string(&self) -> serde_json::Result<String> {
16 serde_json::to_string(self)
17 }
18 pub fn to_string_pretty(&self) -> serde_json::Result<String> {
22 serde_json::to_string_pretty(self)
23 }
24}
25
26#[derive(Deserialize, Serialize, Clone, Default, Debug, PartialEq)]
28pub struct Bmson {
29 pub version: String,
31 pub info: BmsonInfo,
33 pub lines: Option<Vec<BarLine>>,
35 pub bpm_events: Option<Vec<BpmEvent>>,
37 pub stop_events: Option<Vec<StopEvent>>,
39 pub sound_channels: Option<Vec<SoundChannel>>,
41 pub bga: Bga,
43 #[serde(skip_serializing_if = "Option::is_none")]
45 pub scroll_events: Option<Vec<ScrollEvent>>,
46 #[serde(skip_serializing_if = "Option::is_none")]
48 pub mine_channels: Option<Vec<MineChannel>>,
49 #[serde(skip_serializing_if = "Option::is_none")]
51 pub key_channels: Option<Vec<KeyChannel>>,
52}
53
54#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
56pub struct BmsonInfo {
57 pub title: String,
59 #[serde(default)]
61 pub subtitle: String,
62 pub artist: String,
64 pub subartists: Option<Vec<String>>,
66 pub genre: String,
68 #[serde(default = "default_mode_hint")]
72 pub mode_hint: String,
73 pub chart_name: String,
77 pub level: u32,
79 pub init_bpm: f64,
83 #[serde(default = "default_judge_rank")]
87 pub judge_rank: f64,
88 #[serde(default = "default_total")]
94 pub total: f64,
95 pub back_image: Option<String>,
97 pub eyecatch_image: Option<String>,
99 pub title_image: Option<String>,
101 pub banner_image: Option<String>,
103 pub preview_music: Option<String>,
105 #[serde(default = "default_resolution")]
111 pub resolution: u32,
112 #[serde(skip_serializing_if = "Option::is_none")]
114 pub ln_type: Option<LongNoteType>,
115}
116fn default_mode_hint() -> String {
117 "beat-7k".to_string()
118}
119fn default_judge_rank() -> f64 {
120 100.
121}
122fn default_total() -> f64 {
123 100.
124}
125fn default_resolution() -> u32 {
126 240
127}
128impl Default for BmsonInfo {
129 fn default() -> Self {
130 BmsonInfo {
131 title: String::new(),
132 subtitle: String::new(),
133 artist: String::new(),
134 subartists: None,
135 genre: String::new(),
136 mode_hint: "beat-7k".to_string(),
137 chart_name: String::new(),
138 level: 0,
139 init_bpm: 180.,
140 judge_rank: 100.,
141 total: 100.,
142 back_image: None,
143 eyecatch_image: None,
144 title_image: None,
145 banner_image: None,
146 preview_music: None,
147 resolution: 240,
148 ln_type: None,
149 }
150 }
151}
152
153#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
155pub struct BarLine {
156 pub y: u32,
158}
159
160#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
162pub struct SoundChannel {
163 pub name: String,
165 pub notes: Vec<Note>,
167}
168
169#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
171pub struct Note {
172 pub x: Option<u32>,
176 pub y: u32,
178 pub l: u32,
182 pub c: bool,
186 #[serde(skip_serializing_if = "Option::is_none")]
188 pub t: Option<LongNoteType>,
189 #[serde(skip_serializing_if = "Option::is_none")]
193 pub up: Option<bool>,
194}
195
196#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
198pub struct BpmEvent {
199 pub y: u32,
201 pub bpm: f64,
203}
204
205#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
207pub struct StopEvent {
208 pub y: u32,
210 pub duration: u32,
212}
213
214#[derive(Deserialize, Serialize, Clone, Default, Debug, PartialEq)]
216pub struct Bga {
217 pub bga_header: Vec<BgaHeader>,
219 pub bga_events: Vec<BgaEvent>,
221 pub layer_events: Vec<BgaEvent>,
223 pub poor_events: Vec<BgaEvent>,
225}
226
227#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
229pub struct BgaHeader {
230 pub id: u32,
232 pub name: String,
234}
235
236#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
238pub struct BgaEvent {
239 pub y: u32,
241 pub id: u32,
243}
244
245#[derive(
247 serde_repr::Deserialize_repr,
248 serde_repr::Serialize_repr,
249 Clone,
250 Debug,
251 PartialEq,
252)]
253#[repr(u8)]
254pub enum LongNoteType {
255 None = 0,
257 LongNote = 1,
263 ChargeNote = 2,
269 HellChargeNote = 3,
277}
278
279#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
281pub struct ScrollEvent {
282 pub y: f64,
284 pub rate: f64,
286}
287
288#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
290pub struct MineChannel {
291 pub name: String,
293 pub notes: Vec<MineNote>,
295}
296
297#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
299pub struct MineNote {
300 pub x: Option<u32>,
304 pub y: u32,
306 pub damage: f64,
310}
311
312#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
314pub struct KeyChannel {
315 pub name: String,
317 pub notes: Vec<KeyNote>,
319}
320
321#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
323pub struct KeyNote {
324 pub x: Option<u32>,
328 pub y: u32,
330}