use rand::Rng; use crate::objects::{AlbumItem, ChunkHeader, DataSet, Database, JumpTable, LetterJumpEntry, Playlist, PlaylistIndexEntry, PlaylistItem, TrackItem}; #[derive(Debug, serde::Serialize)] pub struct XDatabase { pub header: Option, pub data: Option, pub children: Vec } #[derive(Debug, serde::Serialize)] pub struct XDataSet { pub header: ChunkHeader, pub data: DataSet, pub child: XSomeList } #[derive(Debug, serde::Serialize, Clone)] pub struct XTrackItem { pub header: ChunkHeader, pub data: TrackItem, pub args: Vec } #[derive(Debug, serde::Serialize)] pub struct XAlbumItem { pub header: ChunkHeader, pub data: AlbumItem, pub args: Vec } #[derive(Debug, serde::Serialize)] pub struct XPlaylist { pub header: ChunkHeader, pub data: Playlist, pub args: Vec, pub elems: Vec<(PlaylistItem, Vec)> } #[derive(Debug, serde::Serialize, Clone)] pub enum XPlArgument { String(XArgument), IndexEntry(XPlaylistIndexEntry), LetterJumpEntry(XLetterJump), RawArgument(Vec) } #[derive(Debug, serde::Serialize, Clone)] pub struct XPlaylistIndexEntry { pub data: PlaylistIndexEntry, pub v: Vec } #[derive(Debug, serde::Serialize, Clone)] pub struct XLetterJump { pub data: LetterJumpEntry, pub v: Vec } #[derive(Debug, serde::Serialize, Clone)] pub struct XArgument { pub arg_type: u32, pub val: String } #[derive(Debug, serde::Serialize)] pub enum XSomeList { Playlists(Vec), TrackList(Vec), AlbumList(Vec) } impl XDatabase { pub fn find_dataset(&mut self, data_type: u32) -> &mut XDataSet { self.children.iter_mut().find(|d| d.data.data_type == data_type).unwrap() } pub fn remove_track(&mut self, unique_id: u32) { if let XSomeList::TrackList(tracks) = &mut self.find_dataset(1).child { tracks.retain_mut(|t| t.data.unique_id != unique_id); } if let XSomeList::Playlists(playlists) = &mut self.find_dataset(2).child { for playlist in playlists.iter_mut() { playlist.elems.retain_mut(|t| t.0.track_id != unique_id); } } if let XSomeList::Playlists(playlists) = &mut self.find_dataset(3).child { for playlist in playlists.iter_mut() { playlist.elems.retain_mut(|t| t.0.track_id != unique_id); } } } pub fn get_unique_id(&mut self) -> u32 { if let XSomeList::TrackList(tracks) = &mut self.find_dataset(1).child { if let Some(n) = tracks.iter().map(|t| t.data.unique_id).max() { return n + 1; } } 1 } pub fn add_track(&mut self, track: XTrackItem) { self.add_track_to_playlists(2, &track); self.add_track_to_playlists(3, &track); if let XSomeList::TrackList(tracks) = &mut self.find_dataset(1).child { tracks.push(track); } } fn add_track_to_playlists(&mut self, n: u32, track: &XTrackItem) { if let XSomeList::Playlists(playlists) = &mut self.find_dataset(n).child { let playlist = playlists.last_mut().unwrap(); playlist.data.playlist_item_count += 1; let elem = playlist.elems.last().unwrap(); let mut pl_item = elem.0.clone(); pl_item.track_id = track.data.unique_id; pl_item.group_id = rand::thread_rng().gen_range(10..255); let mut args = elem.1.clone(); if let XPlArgument::RawArgument(raw) = args.last_mut().unwrap() { raw[24] = pl_item.group_id as u8; } playlist.elems.push((pl_item, args)); } } }