use std::io::Read; use crate::constants; use crate::init; use crate::types; use rand::Rng; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct Song { #[serde(skip_serializing_if = "init::is_uuid_nil")] #[serde(alias = "id")] pub id: uuid::Uuid, #[serde(skip_serializing_if = "String::is_empty")] pub title: String, #[serde(skip_serializing_if = "String::is_empty")] pub artist: String, #[serde(skip_serializing_if = "String::is_empty")] pub album: String, #[serde(skip_serializing_if = "String::is_empty")] pub album_artist: String, #[serde(skip_serializing_if = "String::is_empty")] pub genre: String, #[serde(skip_serializing_if = "init::is_zero")] pub year: i32, #[serde(skip_serializing_if = "init::is_dur_not_set")] pub duration: i32, #[serde(skip_serializing_if = "init::is_zero")] pub track: i32, #[serde(skip_serializing_if = "init::is_zero")] pub disc: i32, #[serde(skip_serializing_if = "init::is_zero")] pub disc_count: i32, #[serde(skip_serializing_if = "init::is_zero")] pub track_count: i32, #[serde(skip_serializing_if = "String::is_empty")] pub audio_type: String, #[serde(skip_serializing_if = "String::is_empty")] pub date_created: String, #[serde(skip_serializing_if = "String::is_empty")] pub filename: String, #[serde(skip_serializing_if = "init::is_uuid_nil")] pub user_id: uuid::Uuid, #[serde(skip)] pub data: Vec, #[serde(skip)] pub directory: String, // TODO: Think about what to do with this // #[serde(skip)] // pub album_id: i32, // #[serde(skip)] // pub artist_id: i32, // #[serde(skip)] // pub genre_id: i32, // #[serde(skip)] // pub coverart_id: i32, } impl Song { pub fn to_metadata_json(&self, pretty: bool) -> Result { if pretty { serde_json::to_string_pretty(&self) } else { serde_json::to_string(&self) } } pub fn song_path(&self) -> Result { if self.directory.is_empty() { return Err(std::io::Error::other("Directory does not exist")); } let directory = &self.directory; let mut buffer: String = directory.clone(); let last_index = directory.len() - 1; if let Some(character) = directory.chars().nth(last_index) { if character != '/' { buffer += "/"; } buffer += &self.filename.clone(); Ok(buffer) } else { Err(std::io::Error::other( "Could not access last character of directory", )) } } pub fn to_data(&self) -> Result, std::io::Error> { let path_result = self.song_path(); match path_result { Ok(path) => { let mut file = std::fs::File::open(path)?; let mut buffer: Vec = Vec::new(); file.read_to_end(&mut buffer)?; if buffer.is_empty() { Err(std::io::Error::other("File is empty")) } else { Ok(buffer) } } Err(er) => Err(er), } } pub fn generate_filename(&self, typ: types::MusicTypes, randomize: bool) -> String { let mut filename: String = String::new(); let filename_len = 10; let file_extension = match typ { types::MusicTypes::DefaultMusicExtension => { String::from(constants::file_extensions::audio::DEFAULTMUSICEXTENSION) } types::MusicTypes::WavExtension => { String::from(constants::file_extensions::audio::WAVEXTENSION) } types::MusicTypes::FlacExtension => { String::from(constants::file_extensions::audio::FLACEXTENSION) } types::MusicTypes::MPThreeExtension => { String::from(constants::file_extensions::audio::MPTHREEEXTENSION) } }; if randomize { let some_chars: String = String::from("abcdefghij0123456789"); let mut rng = rand::rng(); for _i in 0..filename_len { let random_number: i32 = rng.random_range(0..=19); let index = random_number as usize; let rando_char = some_chars.chars().nth(index); if let Some(c) = rando_char { filename.push(c); } } } else { filename += "track-output"; } filename += &file_extension; filename } }