Files
drift/src/metadata.rs
Connor Johnstone 70aedb49f2 Some code cleanup
2026-03-04 23:28:29 -05:00

54 lines
1.6 KiB
Rust

use std::path::Path;
use lofty::file::TaggedFileExt;
use lofty::tag::ItemKey;
/// Tags that can be read from a music file.
pub enum Tag {
ArtistName,
ArtistMbid,
TrackTitle,
TrackMbid,
}
impl Tag {
fn item_key(&self) -> ItemKey {
match self {
Tag::ArtistName => ItemKey::TrackArtist,
Tag::ArtistMbid => ItemKey::MusicBrainzArtistId,
Tag::TrackTitle => ItemKey::TrackTitle,
Tag::TrackMbid => ItemKey::MusicBrainzRecordingId,
}
}
}
fn read_tag(path: &Path, key: ItemKey) -> Result<Option<String>, lofty::error::LoftyError> {
let tagged_file = lofty::read_from_path(path)?;
let Some(tag) = tagged_file.primary_tag().or_else(|| tagged_file.first_tag()) else {
return Ok(None);
};
Ok(tag.get_string(key).map(String::from))
}
/// Read multiple tags from a music file in a single file open.
/// Returns a Vec in the same order as the input keys.
pub fn read_tags(path: &Path, keys: &[Tag]) -> Result<Vec<Option<String>>, lofty::error::LoftyError> {
let tagged_file = lofty::read_from_path(path)?;
let Some(tag) = tagged_file.primary_tag().or_else(|| tagged_file.first_tag()) else {
return Ok(vec![None; keys.len()]);
};
Ok(keys
.iter()
.map(|k| tag.get_string(k.item_key()).map(String::from))
.collect())
}
pub fn read_artist_name(path: &Path) -> Result<Option<String>, lofty::error::LoftyError> {
read_tag(path, ItemKey::TrackArtist)
}
pub fn read_artist_mbid(path: &Path) -> Result<Option<String>, lofty::error::LoftyError> {
read_tag(path, ItemKey::MusicBrainzArtistId)
}