Skip to main content

rytm_rs/object/pattern/
de.rs

1use super::{Pattern, Trig};
2use crate::object::pattern::{plock::ParameterLockPool, track::Track};
3use parking_lot::Mutex;
4use serde::de::{
5    self, Deserialize, DeserializeSeed, Deserializer, Error, MapAccess, SeqAccess, Visitor,
6};
7use std::{fmt, sync::Arc};
8
9#[allow(clippy::too_many_lines)]
10impl<'de> Deserialize<'de> for Pattern {
11    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
12    where
13        D: Deserializer<'de>,
14    {
15        struct PatternVisitor;
16
17        impl<'de> Visitor<'de> for PatternVisitor {
18            type Value = Pattern;
19
20            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
21                formatter.write_str("struct Pattern")
22            }
23
24            fn visit_map<V>(self, mut map: V) -> Result<Pattern, V::Error>
25            where
26                V: MapAccess<'de>,
27            {
28                let mut sysex_meta = None;
29                let mut index = None;
30                let mut version = None;
31                let mut tracks: Option<Vec<Track>> = None;
32                let mut fx_track: Option<Arc<Mutex<Track>>> = None;
33                let mut parameter_lock_pool: Option<Arc<Mutex<ParameterLockPool>>> = None;
34                let mut master_length = None;
35                let mut master_change = None;
36                let mut kit_number = None;
37                let mut swing_amount = None;
38                let mut time_mode = None;
39                let mut speed = None;
40                let mut global_quantize = None;
41                let mut bpm = None;
42                let mut pad_scale_per_pattern = None;
43
44                while let Some(key) = map.next_key()? {
45                    match key {
46                        "sysex_meta" => sysex_meta = Some(map.next_value()?),
47                        "index" => index = Some(map.next_value()?),
48                        "version" => version = Some(map.next_value()?),
49                        "fx_track" => {
50                            // Context for the fx_track deserializer
51                            let fx_track_seed = TrackDeserializerSeed {
52                                fx_track_ref: &None, // fx_track does not have a parent, so pass None
53                                parameter_lock_pool: &(parameter_lock_pool.clone()),
54                            };
55                            fx_track =
56                                Some(Arc::new(Mutex::new(map.next_value_seed(fx_track_seed)?)));
57                        }
58                        "tracks" => {
59                            // Context for the tracks array deserializer
60                            let tracks_seed = TracksArrayDeserializerSeed {
61                                fx_track_ref: &(fx_track.clone()),
62                                parameter_lock_pool: &(parameter_lock_pool.clone()),
63                            };
64                            tracks = Some(map.next_value_seed(tracks_seed)?);
65                        }
66                        "master_length" => master_length = Some(map.next_value()?),
67                        "master_change" => master_change = Some(map.next_value()?),
68                        "kit_number" => kit_number = Some(map.next_value()?),
69                        "swing_amount" => swing_amount = Some(map.next_value()?),
70                        "time_mode" => time_mode = Some(map.next_value()?),
71                        "speed" => speed = Some(map.next_value()?),
72                        "global_quantize" => global_quantize = Some(map.next_value()?),
73                        "bpm" => bpm = Some(map.next_value()?),
74                        "pad_scale_per_pattern" => pad_scale_per_pattern = Some(map.next_value()?),
75                        "parameter_lock_pool" => {
76                            let parameter_lock_pool_value: ParameterLockPool = map.next_value()?;
77                            parameter_lock_pool =
78                                Some(Arc::new(Mutex::new(parameter_lock_pool_value)));
79                        }
80                        _ => return Err(V::Error::unknown_field(key, FIELDS)),
81                    }
82                }
83
84                Ok(Pattern {
85                    sysex_meta: sysex_meta.ok_or_else(|| V::Error::missing_field("sysex_meta"))?,
86                    index: index.ok_or_else(|| V::Error::missing_field("index"))?,
87                    version: version.ok_or_else(|| V::Error::missing_field("version"))?,
88                    fx_track: fx_track.ok_or_else(|| V::Error::missing_field("fx_track"))?,
89                    tracks: tracks.ok_or_else(|| V::Error::missing_field("tracks"))?,
90                    master_length: master_length
91                        .ok_or_else(|| V::Error::missing_field("master_length"))?,
92                    master_change: master_change
93                        .ok_or_else(|| V::Error::missing_field("master_change"))?,
94                    kit_number: kit_number.ok_or_else(|| V::Error::missing_field("kit_number"))?,
95                    swing_amount: swing_amount
96                        .ok_or_else(|| V::Error::missing_field("swing_amount"))?,
97                    time_mode: time_mode.ok_or_else(|| V::Error::missing_field("time_mode"))?,
98                    speed: speed.ok_or_else(|| V::Error::missing_field("speed"))?,
99                    global_quantize: global_quantize
100                        .ok_or_else(|| V::Error::missing_field("global_quantize"))?,
101                    bpm: bpm.ok_or_else(|| V::Error::missing_field("bpm"))?,
102                    pad_scale_per_pattern: pad_scale_per_pattern
103                        .ok_or_else(|| V::Error::missing_field("pad_scale_per_pattern"))?,
104                    parameter_lock_pool: parameter_lock_pool
105                        .ok_or_else(|| V::Error::missing_field("parameter_lock_pool"))?,
106                })
107            }
108        }
109
110        const FIELDS: &[&str] = &[
111            "sysex_meta",
112            "index",
113            "version",
114            "tracks",
115            "fx_track",
116            "parameter_lock_pool",
117            "master_length",
118            "master_change",
119            "kit_number",
120            "swing_amount",
121            "time_mode",
122            "speed",
123            "global_quantize",
124            "bpm",
125            "pad_scale_per_pattern",
126        ];
127
128        deserializer.deserialize_struct("Pattern", FIELDS, PatternVisitor)
129    }
130}
131
132// Tracks array deserializer
133struct TracksArrayDeserializerSeed<'a> {
134    fx_track_ref: &'a Option<Arc<Mutex<Track>>>,
135    parameter_lock_pool: &'a Option<Arc<Mutex<ParameterLockPool>>>,
136}
137
138impl<'a, 'de> DeserializeSeed<'de> for TracksArrayDeserializerSeed<'a> {
139    type Value = Vec<Track>;
140
141    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
142    where
143        D: Deserializer<'de>,
144    {
145        struct ArrayVisitor<'a> {
146            fx_track_ref: &'a Option<Arc<Mutex<Track>>>,
147            parameter_lock_pool: &'a Option<Arc<Mutex<ParameterLockPool>>>,
148        }
149
150        impl<'a, 'de> Visitor<'de> for ArrayVisitor<'a> {
151            type Value = Vec<Track>;
152
153            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
154                formatter.write_str("an array of 12 tracks")
155            }
156
157            fn visit_seq<A>(self, mut seq: A) -> Result<Vec<Track>, A::Error>
158            where
159                A: SeqAccess<'de>,
160            {
161                let mut tracks = Vec::with_capacity(12);
162                for i in 0..12 {
163                    let track_seed = TrackDeserializerSeed {
164                        fx_track_ref: self.fx_track_ref,
165                        parameter_lock_pool: self.parameter_lock_pool,
166                    };
167                    tracks.push(
168                        seq.next_element_seed(track_seed)?
169                            .ok_or_else(|| Error::invalid_length(i, &self))?,
170                    );
171                }
172                Ok(tracks)
173            }
174        }
175
176        deserializer.deserialize_seq(ArrayVisitor {
177            fx_track_ref: self.fx_track_ref,
178            parameter_lock_pool: self.parameter_lock_pool,
179        })
180    }
181}
182
183// Context for a single track deserializer
184pub struct TrackDeserializerSeed<'a> {
185    pub fx_track_ref: &'a Option<Arc<Mutex<Track>>>,
186    pub parameter_lock_pool: &'a Option<Arc<Mutex<ParameterLockPool>>>,
187}
188
189impl<'a, 'de> de::DeserializeSeed<'de> for TrackDeserializerSeed<'a> {
190    type Value = Track;
191
192    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
193    where
194        D: Deserializer<'de>,
195    {
196        deserializer.deserialize_struct(
197            "Track",
198            FIELDS,
199            TrackVisitor {
200                fx_track_ref: self.fx_track_ref,
201                parameter_lock_pool: self.parameter_lock_pool,
202            },
203        )
204    }
205}
206
207struct TrackVisitor<'a> {
208    fx_track_ref: &'a Option<Arc<Mutex<Track>>>,
209    parameter_lock_pool: &'a Option<Arc<Mutex<ParameterLockPool>>>,
210}
211
212impl<'a, 'de> de::Visitor<'de> for TrackVisitor<'a> {
213    type Value = Track;
214
215    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
216        formatter.write_str("struct Track")
217    }
218
219    #[allow(clippy::too_many_lines)]
220    fn visit_map<V>(self, mut map: V) -> Result<Track, V::Error>
221    where
222        V: de::MapAccess<'de>,
223    {
224        // Initialize all Track fields to None or default value
225        let mut is_owner_pattern_work_buffer = None;
226        let mut owner_pattern_index = None;
227        let mut index = None;
228        let mut trigs = None;
229        let mut default_trig_flags = None;
230        let mut default_trig_note = None;
231        let mut default_trig_velocity = None;
232        let mut default_trig_note_length = None;
233        let mut default_trig_probability = None;
234        let mut number_of_steps = None;
235        let mut quantize_amount = None;
236        let mut sends_midi = None;
237        let mut speed = None;
238        let mut euclidean_mode = None;
239        let mut euclidean_pl1 = None;
240        let mut euclidean_pl2 = None;
241        let mut euclidean_ro1 = None;
242        let mut euclidean_ro2 = None;
243        let mut euclidean_tro = None;
244        let mut pad_scale = None;
245        let mut root_note = None;
246        let mut __maybe_useful_flag_from_default_trig_note = None;
247        let mut __maybe_useful_flags_from_flags_and_speed = None;
248
249        while let Some(key) = map.next_key()? {
250            match key {
251                "is_owner_pattern_work_buffer" => {
252                    is_owner_pattern_work_buffer = Some(map.next_value()?);
253                }
254                "owner_pattern_index" => owner_pattern_index = Some(map.next_value()?),
255                "index" => index = Some(map.next_value()?),
256                "trigs" => {
257                    // Pass context into the trigs array deserializer
258                    trigs = Some(map.next_value_seed(TrigsArrayVisitor {
259                        parameter_lock_pool: self.parameter_lock_pool.clone(),
260                        fx_track_ref: self.fx_track_ref.clone(),
261                    })?);
262                }
263                "default_trig_flags" => default_trig_flags = Some(map.next_value()?),
264                "default_trig_note" => default_trig_note = Some(map.next_value()?),
265                "default_trig_velocity" => default_trig_velocity = Some(map.next_value()?),
266                "default_trig_note_length" => default_trig_note_length = Some(map.next_value()?),
267                "default_trig_probability" => default_trig_probability = Some(map.next_value()?),
268                "number_of_steps" => number_of_steps = Some(map.next_value()?),
269                "quantize_amount" => quantize_amount = Some(map.next_value()?),
270                "sends_midi" => sends_midi = Some(map.next_value()?),
271                "speed" => speed = Some(map.next_value()?),
272                "euclidean_mode" => euclidean_mode = Some(map.next_value()?),
273                "euclidean_pl1" => euclidean_pl1 = Some(map.next_value()?),
274                "euclidean_pl2" => euclidean_pl2 = Some(map.next_value()?),
275                "euclidean_ro1" => euclidean_ro1 = Some(map.next_value()?),
276                "euclidean_ro2" => euclidean_ro2 = Some(map.next_value()?),
277                "euclidean_tro" => euclidean_tro = Some(map.next_value()?),
278                "pad_scale" => pad_scale = Some(map.next_value()?),
279                "root_note" => root_note = Some(map.next_value()?),
280                "__maybe_useful_flag_from_default_trig_note" => {
281                    __maybe_useful_flag_from_default_trig_note = Some(map.next_value()?);
282                }
283                "__maybe_useful_flags_from_flags_and_speed" => {
284                    __maybe_useful_flags_from_flags_and_speed = Some(map.next_value()?);
285                }
286                _ => return Err(de::Error::unknown_field(key, FIELDS)),
287            }
288        }
289
290        Ok(Track {
291            is_owner_pattern_work_buffer: is_owner_pattern_work_buffer
292                .ok_or_else(|| de::Error::missing_field("is_owner_pattern_work_buffer"))?,
293            owner_pattern_index: owner_pattern_index
294                .ok_or_else(|| de::Error::missing_field("owner_pattern_index"))?,
295            index: index.ok_or_else(|| de::Error::missing_field("index"))?,
296            trigs: trigs.ok_or_else(|| de::Error::missing_field("trigs"))?,
297            default_trig_flags: default_trig_flags
298                .ok_or_else(|| de::Error::missing_field("default_trig_flags"))?,
299            default_trig_note: default_trig_note
300                .ok_or_else(|| de::Error::missing_field("default_trig_note"))?,
301            default_trig_velocity: default_trig_velocity
302                .ok_or_else(|| de::Error::missing_field("default_trig_velocity"))?,
303            default_trig_note_length: default_trig_note_length
304                .ok_or_else(|| de::Error::missing_field("default_trig_note_length"))?,
305            default_trig_probability: default_trig_probability
306                .ok_or_else(|| de::Error::missing_field("default_trig_probability"))?,
307            number_of_steps: number_of_steps
308                .ok_or_else(|| de::Error::missing_field("number_of_steps"))?,
309            quantize_amount: quantize_amount
310                .ok_or_else(|| de::Error::missing_field("quantize_amount"))?,
311            sends_midi: sends_midi.ok_or_else(|| de::Error::missing_field("sends_midi"))?,
312            speed: speed.ok_or_else(|| de::Error::missing_field("speed"))?,
313            euclidean_mode: euclidean_mode
314                .ok_or_else(|| de::Error::missing_field("euclidean_mode"))?,
315            euclidean_pl1: euclidean_pl1
316                .ok_or_else(|| de::Error::missing_field("euclidean_pl1"))?,
317            euclidean_pl2: euclidean_pl2
318                .ok_or_else(|| de::Error::missing_field("euclidean_pl2"))?,
319            euclidean_ro1: euclidean_ro1
320                .ok_or_else(|| de::Error::missing_field("euclidean_ro1"))?,
321            euclidean_ro2: euclidean_ro2
322                .ok_or_else(|| de::Error::missing_field("euclidean_ro2"))?,
323            euclidean_tro: euclidean_tro
324                .ok_or_else(|| de::Error::missing_field("euclidean_tro"))?,
325            pad_scale: pad_scale.ok_or_else(|| de::Error::missing_field("pad_scale"))?,
326            root_note: root_note.ok_or_else(|| de::Error::missing_field("root_note"))?,
327            __maybe_useful_flag_from_default_trig_note: __maybe_useful_flag_from_default_trig_note
328                .ok_or_else(|| {
329                    de::Error::missing_field("__maybe_useful_flag_from_default_trig_note")
330                })?,
331            __maybe_useful_flags_from_flags_and_speed: __maybe_useful_flags_from_flags_and_speed
332                .ok_or_else(|| {
333                    de::Error::missing_field("__maybe_useful_flags_from_flags_and_speed")
334                })?,
335            // Inject the context to the track
336            fx_track_ref: self.fx_track_ref.clone(),
337            parameter_lock_pool: self.parameter_lock_pool.clone(),
338        })
339    }
340}
341
342const FIELDS: &[&str] = &[
343    "is_owner_pattern_work_buffer",
344    "owner_pattern_index",
345    "index",
346    "trigs",
347    "default_trig_flags",
348    "default_trig_note",
349    "default_trig_velocity",
350    "default_trig_note_length",
351    "default_trig_probability",
352    "number_of_steps",
353    "quantize_amount",
354    "sends_midi",
355    "speed",
356    "euclidean_mode",
357    "euclidean_pl1",
358    "euclidean_pl2",
359    "euclidean_ro1",
360    "euclidean_ro2",
361    "euclidean_tro",
362    "pad_scale",
363    "root_note",
364    "__maybe_useful_flag_from_default_trig_note",
365    "__maybe_useful_flags_from_flags_and_speed",
366];
367
368// Trigs array deserializer
369pub struct TrigsArrayVisitor {
370    pub parameter_lock_pool: Option<Arc<Mutex<ParameterLockPool>>>,
371    pub fx_track_ref: Option<Arc<Mutex<Track>>>,
372}
373
374impl<'de> de::DeserializeSeed<'de> for TrigsArrayVisitor {
375    type Value = Vec<Trig>;
376
377    fn deserialize<D>(self, deserializer: D) -> Result<Vec<Trig>, D::Error>
378    where
379        D: Deserializer<'de>,
380    {
381        struct ArrayVisitor {
382            pub parameter_lock_pool: Option<Arc<Mutex<ParameterLockPool>>>,
383            pub fx_track_ref: Option<Arc<Mutex<Track>>>,
384        }
385
386        impl<'de> Visitor<'de> for ArrayVisitor {
387            type Value = Vec<Trig>;
388
389            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
390                formatter.write_str("an array of 64 elements")
391            }
392
393            fn visit_seq<A>(self, mut seq: A) -> Result<Vec<Trig>, A::Error>
394            where
395                A: SeqAccess<'de>,
396            {
397                let mut trigs = Vec::with_capacity(64);
398                for i in 0..64 {
399                    let mut trig: Trig = seq
400                        .next_element()?
401                        .ok_or_else(|| serde::de::Error::invalid_length(i, &self))?;
402
403                    trig.parameter_lock_pool
404                        .clone_from(&self.parameter_lock_pool);
405                    trig.fx_track_ref.clone_from(&self.fx_track_ref);
406
407                    trigs.push(trig);
408                }
409                Ok(trigs)
410            }
411        }
412
413        deserializer.deserialize_seq(ArrayVisitor {
414            parameter_lock_pool: self.parameter_lock_pool.clone(),
415            fx_track_ref: self.fx_track_ref,
416        })
417    }
418}