Compare commits

..

4 Commits

Author SHA1 Message Date
5b9ad2553f Changed workflow linux distro
Some checks failed
Rust Build / build (pull_request) Blocked by required conditions
Release Tagging / release (pull_request) Successful in 26s
Rust Build / Check (pull_request) Successful in 9m57s
Rust Build / Test Suite (pull_request) Failing after 10m23s
Rust Build / Rustfmt (pull_request) Successful in 9m55s
Rust Build / Clippy (pull_request) Successful in 9m40s
2026-03-22 15:49:16 -04:00
27e74703bc Rust version bump to 1.94 2026-03-22 15:47:34 -04:00
e9546ce0a7 Updating rust version in workflow
Some checks failed
Release Tagging / release (pull_request) Successful in 27s
Rust Build / Check (pull_request) Successful in 9m52s
Rust Build / Test Suite (pull_request) Successful in 10m2s
Rust Build / Rustfmt (pull_request) Successful in 10m51s
Rust Build / build (pull_request) Successful in 10m9s
Rust Build / Clippy (pull_request) Failing after 14m58s
2026-03-22 15:45:18 -04:00
b73ffce048 tsk-50: Create functionality to extract song properties (#52)
All checks were successful
Rust Build / Clippy (push) Successful in 43s
Rust Build / Check (push) Successful in 32s
Release Tagging / release (push) Successful in 36s
Rust Build / Test Suite (push) Successful in 33s
Rust Build / Rustfmt (push) Successful in 48s
Rust Build / build (push) Successful in 36s
Release Tagging / release (pull_request) Successful in 34s
Rust Build / Check (pull_request) Successful in 9m58s
Rust Build / Test Suite (pull_request) Successful in 10m18s
Rust Build / Rustfmt (pull_request) Successful in 10m5s
Rust Build / Clippy (pull_request) Successful in 10m9s
Rust Build / build (pull_request) Successful in 10m8s
Closes #50

Reviewed-on: #52
Co-authored-by: phoenix <kundeng00@pm.me>
Co-committed-by: phoenix <kundeng00@pm.me>
2025-11-06 17:31:37 +00:00
8 changed files with 187 additions and 75 deletions

View File

@@ -10,7 +10,7 @@ on:
jobs:
release:
runs-on: ubuntu-24.04
runs-on: debian-13
steps:
- name: Checkout code
uses: actions/checkout@v5
@@ -20,7 +20,7 @@ jobs:
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: 1.90.0
toolchain: 1.94
components: cargo
- name: Extract Version from Cargo.toml

View File

@@ -11,12 +11,12 @@ on:
jobs:
check:
name: Check
runs-on: ubuntu-24.04
runs-on: debian-13
steps:
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.90.0
toolchain: 1.94
- run: |
mkdir -p ~/.ssh
echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key
@@ -28,13 +28,13 @@ jobs:
test:
name: Test Suite
runs-on: ubuntu-24.04
runs-on: debian-13
needs: setup_ssh
steps:
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.90.0
toolchain: 1.94
- run: |
mkdir -p ~/.ssh
echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key
@@ -46,13 +46,13 @@ jobs:
fmt:
name: Rustfmt
runs-on: ubuntu-24.04
runs-on: debian-13
needs: setup_ssh
steps:
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.90.0
toolchain: 1.94
- run: rustup component add rustfmt
- run: |
mkdir -p ~/.ssh
@@ -65,13 +65,13 @@ jobs:
clippy:
name: Clippy
runs-on: ubuntu-24.04
runs-on: debian-13
needs: setup_ssh
steps:
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.90.0
toolchain: 1.94
- run: rustup component add clippy
- run: |
mkdir -p ~/.ssh
@@ -84,13 +84,13 @@ jobs:
build:
name: build
runs-on: ubuntu-24.04
runs-on: debian-13
needs: setup_ssh
steps:
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.90.0
toolchain: 1.94
- run: |
mkdir -p ~/.ssh
echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/gitlab_deploy_key

2
Cargo.lock generated
View File

@@ -104,7 +104,7 @@ dependencies = [
[[package]]
name = "icarus_meta"
version = "0.4.4"
version = "0.4.5"
dependencies = [
"imghdr",
"infer",

View File

@@ -1,8 +1,8 @@
[package]
name = "icarus_meta"
version = "0.4.4"
version = "0.4.5"
edition = "2024"
rust-version = "1.90"
rust-version = "1.94"
[dependencies]
lofty = { version = "0.22.4" }

View File

@@ -19,10 +19,7 @@ pub mod test_util {
Err(err) => Err(err),
}
}
pub fn get_full_path(
directory: &String,
filename: &String,
) -> Result<String, std::io::Error> {
pub fn get_full_path(directory: &str, filename: &str) -> Result<String, std::io::Error> {
match path_buf(directory, filename) {
Ok(pf) => Ok(pf.display().to_string()),
Err(err) => Err(err),
@@ -39,6 +36,12 @@ pub mod test_util {
std::fs::copy(src_path, dest_path)
}
pub fn remove_file(filepath: &str) -> Result<(), std::io::Error> {
let f_path = std::path::Path::new(filepath);
std::fs::remove_file(f_path)
}
pub fn get_data_from_file(source_path: &str) -> Result<Vec<u8>, std::io::Error> {
match std::fs::File::open(source_path) {
Ok(mut file) => {
@@ -52,13 +55,23 @@ pub mod test_util {
}
}
pub fn file_exists(directory: &String, filename: &String) -> Result<bool, std::io::Error> {
pub fn file_exists(directory: &str, filename: &str) -> Result<bool, std::io::Error> {
match path_buf(directory, filename) {
Ok(pf) => Ok(pf.exists()),
Err(err) => Err(err),
}
}
pub fn generate_newfilepath(directory: &str) -> Result<String, std::io::Error> {
match generate_filename() {
Ok(filename) => match get_full_path(directory, &filename) {
Ok(filepath) => Ok(filepath),
Err(err) => Err(err),
},
Err(err) => Err(err),
}
}
pub fn generate_filename() -> Result<String, std::io::Error> {
let mut filename = String::from("track-");
let length = 20;
@@ -78,10 +91,7 @@ pub mod test_util {
Ok(format!("{filename}.flac"))
}
fn path_buf(
directory: &String,
filename: &String,
) -> Result<std::path::PathBuf, std::io::Error> {
fn path_buf(directory: &str, filename: &str) -> Result<std::path::PathBuf, std::io::Error> {
let dir_path = std::path::Path::new(&directory);
Ok(dir_path.join(filename))
}

View File

@@ -1,51 +0,0 @@
use lofty::file::AudioFile;
pub fn get_duration(song_path: &String) -> Result<std::time::Duration, std::io::Error> {
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:?}");
}
}
}
}

14
src/properties/audio.rs Normal file
View File

@@ -0,0 +1,14 @@
use lofty::file::AudioFile;
pub fn get_properties(songpath: &str) -> Result<lofty::flac::FlacProperties, std::io::Error> {
match std::fs::File::open(songpath) {
Ok(mut content) => {
match lofty::flac::FlacFile::read_from(&mut content, lofty::config::ParseOptions::new())
{
Ok(flac_file) => Ok(*flac_file.properties()),
Err(err) => Err(std::io::Error::other(err.to_string())),
}
}
Err(err) => Err(err),
}
}

139
src/properties/mod.rs Normal file
View File

@@ -0,0 +1,139 @@
pub mod audio;
#[derive(Clone, Debug, Default)]
pub struct SongProperties {
pub duration: std::time::Duration,
pub sample_rate: u32,
pub bitrate: u32,
pub overall_bitrate: u32,
pub bit_depth: u8,
pub channels: u8,
}
pub fn get_song_properties(song_path: &str) -> Result<SongProperties, std::io::Error> {
match audio::get_properties(song_path) {
Ok(flac_properties) => Ok(SongProperties {
duration: flac_properties.duration(),
sample_rate: flac_properties.sample_rate(),
bitrate: flac_properties.audio_bitrate(),
overall_bitrate: flac_properties.overall_bitrate(),
bit_depth: flac_properties.bit_depth(),
channels: flac_properties.channels(),
}),
Err(err) => Err(err),
}
}
pub fn get_duration(song_path: &str) -> Result<std::time::Duration, std::io::Error> {
match get_song_properties(song_path) {
Ok(song_properties) => Ok(song_properties.duration),
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();
let new_filepath = test_util::util::generate_newfilepath(&dir).unwrap();
match test_util::util::copy_file(&filepath, &new_filepath) {
Ok(_) => match super::get_duration(&new_filepath) {
Ok(duration) => {
test_util::util::remove_file(&new_filepath).unwrap();
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:?}");
}
}
}
Err(err) => {
assert!(false, "Error: {err:?}");
}
}
}
#[test]
fn test_song_properties() {
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();
let new_filepath = test_util::util::generate_newfilepath(&dir).unwrap();
match test_util::util::copy_file(&filepath, &new_filepath) {
Ok(_) => match super::get_song_properties(&new_filepath) {
Ok(song_properties) => {
test_util::util::remove_file(&new_filepath).unwrap();
let song_duration: u64 = 41;
let bitrate: u32 = 1;
let overall_bitrate: u32 = 3;
let bit_depth: u8 = 24;
let channels: u8 = 2;
let fetched_song_duration = song_properties.duration.as_secs();
let fetched_bitrate = song_properties.bitrate;
let fetched_overall_bitrate = song_properties.overall_bitrate;
let fetched_bit_depth = song_properties.bit_depth;
let fetched_channels = song_properties.channels;
assert_eq!(
song_duration, fetched_song_duration,
"Durations should match, but they don't {song_duration} {fetched_song_duration} ({song_properties:?})"
);
assert_eq!(
bitrate, fetched_bitrate,
"Bitrates do not match {bitrate:?} {fetched_bitrate:?} {song_properties:?}"
);
assert_eq!(
overall_bitrate, fetched_overall_bitrate,
"Overall bitrates do not match {overall_bitrate:?} {fetched_overall_bitrate:?} {song_properties:?}"
);
assert_eq!(
bit_depth, fetched_bit_depth,
"Bit depth do not match {bit_depth:?} {fetched_bit_depth:?} {song_properties:?}"
);
assert_eq!(
channels, fetched_channels,
"Channels do not match {channels:?} {fetched_channels:?} {song_properties:?}"
);
}
Err(err) => {
assert!(false, "Error: {err:?}");
}
},
Err(err) => {
assert!(false, "Error: {err:?}");
}
}
}
Err(err) => {
assert!(false, "Error: {err:?}");
}
}
}
}