54 lines
1.6 KiB
Rust
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)
|
|
}
|
|
|