From 5baecbaa9af8af626bb38de0ef3002463909d01c Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Jul 2025 21:45:48 +0000 Subject: [PATCH] Duration (#40) Reviewed-on: https://git.kundeng.us/phoenix/icarus_meta/pulls/40 Co-authored-by: phoenix Co-committed-by: phoenix --- src/lib.rs | 64 ++++++++++++++++++++++++++++++++++ src/meta.rs | 88 +++++------------------------------------------ src/properties.rs | 51 +++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 79 deletions(-) create mode 100644 src/properties.rs diff --git a/src/lib.rs b/src/lib.rs index 1009908..bbf790d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,66 @@ pub mod meta; +pub mod properties; pub mod types; + +pub mod test_util { + pub mod util { + use std::io::{self, Write}; + + // Function to save a Vec to a file + pub fn save_bytes_to_file(bytes: &[u8], file_path: &String) -> io::Result<()> { + let file = std::path::Path::new(file_path); + let mut file = std::fs::File::create(file)?; + + match file.write_all(bytes) { + Ok(_res) => Ok(()), + Err(err) => Err(err), + } + } + pub fn get_full_path( + directory: &String, + filename: &String, + ) -> Result { + match path_buf(directory, filename) { + Ok(pf) => Ok(pf.display().to_string()), + Err(err) => Err(err), + } + } + + pub fn copy_file( + source_path: &String, + destination_path: &String, + ) -> Result { + let src_path = std::path::Path::new(source_path); + let dest_path = std::path::Path::new(destination_path); + + std::fs::copy(src_path, dest_path) + } + + pub fn file_exists(directory: &String, filename: &String) -> Result { + match path_buf(directory, filename) { + Ok(pf) => Ok(pf.exists()), + Err(err) => Err(err), + } + } + + fn path_buf( + directory: &String, + filename: &String, + ) -> Result { + let dir_path = std::path::Path::new(&directory); + Ok(dir_path.join(filename)) + } + + pub const TESTFILEDIRECTORY: &str = "tests/sample_tracks3"; + + pub fn get_filename(track: i32) -> String { + const FLAC_EXTENSION: &str = ".flac"; + + if track < 10 { + format!("track0{track}{FLAC_EXTENSION}") + } else { + format!("track{track}{FLAC_EXTENSION}") + } + } + } +} diff --git a/src/meta.rs b/src/meta.rs index 3deb1a3..b3e4174 100644 --- a/src/meta.rs +++ b/src/meta.rs @@ -275,83 +275,10 @@ pub mod metadata { #[cfg(test)] mod tests { - use util::{file_exists, get_full_path}; - - use super::*; - - mod util { - - use std::io::{self, Write}; - - // Function to save a Vec to a file - pub fn save_bytes_to_file(bytes: &[u8], file_path: &String) -> io::Result<()> { - let file = std::path::Path::new(file_path); - let mut file = std::fs::File::create(file)?; - - match file.write_all(bytes) { - Ok(_res) => Ok(()), - Err(err) => Err(err), - } - } - pub fn get_full_path( - directory: &String, - filename: &String, - ) -> Result { - match path_buf(directory, filename) { - Ok(pf) => Ok(pf.display().to_string()), - Err(err) => Err(err), - } - } - - pub fn copy_file( - source_path: &String, - destination_path: &String, - ) -> Result { - let src_path = std::path::Path::new(source_path); - let dest_path = std::path::Path::new(destination_path); - - match std::fs::copy(src_path, dest_path) { - Ok(bytes) => Ok(bytes), - Err(err) => Err(err), - } - } - - pub fn file_exists(directory: &String, filename: &String) -> Result { - match path_buf(directory, filename) { - Ok(pf) => Ok(pf.exists()), - Err(err) => Err(err), - } - } - - fn path_buf( - directory: &String, - filename: &String, - ) -> Result { - let dir_path = std::path::Path::new(&directory); - Ok(dir_path.join(filename)) - } - - pub const TESTFILEDIRECTORY: &str = "tests/sample_tracks3"; - - pub fn get_filename(track: i32) -> String { - let mut filename = String::from("track"); - - if track < 10 { - filename += "0"; - filename += &track.to_string(); - } else { - filename += &track.to_string(); - } - - filename += ".flac"; - - filename - } - } - mod get { - use super::metadata::get_meta; - use super::*; + use super::super::metadata::get_meta; + use crate::test_util::util; + use crate::test_util::util::{file_exists, get_full_path}; use crate::types; #[test] @@ -605,8 +532,9 @@ mod tests { } mod set { - use super::metadata::{get_meta, set_meta}; - use super::*; + use super::super::metadata::{get_meta, set_meta}; + use crate::test_util::util; + use crate::test_util::util::{file_exists, get_full_path}; use crate::types; #[test] @@ -1142,7 +1070,9 @@ mod tests { mod pictures { - use super::*; + use super::super::*; + use crate::test_util::util; + use crate::test_util::util::{file_exists, get_full_path}; #[test] fn test_get_picture() { diff --git a/src/properties.rs b/src/properties.rs new file mode 100644 index 0000000..3e28031 --- /dev/null +++ b/src/properties.rs @@ -0,0 +1,51 @@ +use lofty::file::AudioFile; + +pub fn get_duration(song_path: &String) -> Result { + match std::fs::File::open(song_path) { + Ok(mut content) => { + match lofty::flac::FlacFile::read_from(&mut content, lofty::config::ParseOptions::new()) + { + Ok(flac_file) => { + let properties = flac_file.properties(); + Ok(properties.duration()) + } + Err(err) => Err(std::io::Error::other(err.to_string())), + } + } + Err(err) => Err(err), + } +} + +#[cfg(test)] +mod tests { + use crate::test_util; + + #[test] + fn test_get_duration() { + let filename = test_util::util::get_filename(1); + let dir = String::from(test_util::util::TESTFILEDIRECTORY); + + match test_util::util::file_exists(&dir, &filename) { + Ok(_) => { + let filepath = test_util::util::get_full_path(&dir, &filename).unwrap(); + match super::get_duration(&filepath) { + Ok(duration) => { + let song_duration: u64 = 41; + let fetched_song_duration = duration.as_secs(); + + assert_eq!( + song_duration, fetched_song_duration, + "Durations should match, but they don't {song_duration} {fetched_song_duration} ({duration:?})" + ); + } + Err(err) => { + assert!(false, "Error: {err:?}"); + } + } + } + Err(err) => { + assert!(false, "Error: {err:?}"); + } + } + } +}