rosu_map/section/
editor.rs1use crate::{
2 decode::{DecodeBeatmap, DecodeState},
3 util::{KeyValue, ParseNumberError, StrExt},
4 Beatmap,
5};
6
7#[derive(Clone, Debug, PartialEq)]
9pub struct Editor {
10 pub bookmarks: Vec<i32>,
11 pub distance_spacing: f64,
12 pub beat_divisor: i32,
13 pub grid_size: i32,
14 pub timeline_zoom: f64,
15}
16
17impl Default for Editor {
18 #[allow(clippy::default_trait_access)]
19 fn default() -> Self {
20 Self {
21 bookmarks: Default::default(),
22 distance_spacing: 1.0,
23 beat_divisor: 4,
24 grid_size: Default::default(),
25 timeline_zoom: 1.0,
26 }
27 }
28}
29
30impl From<Editor> for Beatmap {
31 fn from(editor: Editor) -> Self {
32 Self {
33 bookmarks: editor.bookmarks,
34 distance_spacing: editor.distance_spacing,
35 beat_divisor: editor.beat_divisor,
36 grid_size: editor.grid_size,
37 timeline_zoom: editor.timeline_zoom,
38 ..Self::default()
39 }
40 }
41}
42
43section_keys! {
44 pub enum EditorKey {
46 Bookmarks,
47 DistanceSpacing,
48 BeatDivisor,
49 GridSize,
50 TimelineZoom,
51 }
52}
53
54thiserror! {
55 #[derive(Debug)]
57 pub enum ParseEditorError {
58 #[error("failed to parse number")]
59 Number(#[from] ParseNumberError),
60 }
61}
62
63pub type EditorState = Editor;
65
66impl DecodeState for EditorState {
67 fn create(_: i32) -> Self {
68 Self::default()
69 }
70}
71
72impl DecodeBeatmap for Editor {
73 type Error = ParseEditorError;
74 type State = EditorState;
75
76 fn parse_general(_: &mut Self::State, _: &str) -> Result<(), Self::Error> {
77 Ok(())
78 }
79
80 fn parse_editor(state: &mut Self::State, line: &str) -> Result<(), Self::Error> {
81 let Ok(KeyValue { key, value }) = KeyValue::parse(line.trim_comment()) else {
82 return Ok(());
83 };
84
85 match key {
86 EditorKey::Bookmarks => {
87 state.bookmarks = value
88 .split(',')
89 .map(str::parse)
90 .filter_map(Result::ok)
91 .collect();
92 }
93 EditorKey::DistanceSpacing => state.distance_spacing = value.parse_num()?,
94 EditorKey::BeatDivisor => state.beat_divisor = value.parse_num()?,
95 EditorKey::GridSize => state.grid_size = value.parse_num()?,
96 EditorKey::TimelineZoom => state.timeline_zoom = value.parse_num()?,
97 }
98
99 Ok(())
100 }
101
102 fn parse_metadata(_: &mut Self::State, _: &str) -> Result<(), Self::Error> {
103 Ok(())
104 }
105
106 fn parse_difficulty(_: &mut Self::State, _: &str) -> Result<(), Self::Error> {
107 Ok(())
108 }
109
110 fn parse_events(_: &mut Self::State, _: &str) -> Result<(), Self::Error> {
111 Ok(())
112 }
113
114 fn parse_timing_points(_: &mut Self::State, _: &str) -> Result<(), Self::Error> {
115 Ok(())
116 }
117
118 fn parse_colors(_: &mut Self::State, _: &str) -> Result<(), Self::Error> {
119 Ok(())
120 }
121
122 fn parse_hit_objects(_: &mut Self::State, _: &str) -> Result<(), Self::Error> {
123 Ok(())
124 }
125
126 fn parse_variables(_: &mut Self::State, _: &str) -> Result<(), Self::Error> {
127 Ok(())
128 }
129
130 fn parse_catch_the_beat(_: &mut Self::State, _: &str) -> Result<(), Self::Error> {
131 Ok(())
132 }
133
134 fn parse_mania(_: &mut Self::State, _: &str) -> Result<(), Self::Error> {
135 Ok(())
136 }
137}