70 lines
2.2 KiB
Rust
70 lines
2.2 KiB
Rust
use std::path::Path;
|
|
|
|
use lofty::file::TaggedFileExt;
|
|
use lofty::tag::{ItemKey, ItemValue};
|
|
|
|
/// A single key-value metadata item from a tag.
|
|
pub struct TagEntry {
|
|
pub key: String,
|
|
pub value: String,
|
|
}
|
|
|
|
/// Read all metadata items from a music file.
|
|
/// Returns `None` if no tags are present, otherwise a list of all tag entries.
|
|
pub fn read_all_metadata(path: &Path) -> Result<Option<Vec<TagEntry>>, 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);
|
|
};
|
|
|
|
let entries = tag
|
|
.items()
|
|
.filter_map(|item| {
|
|
let value = match item.value() {
|
|
ItemValue::Text(t) | ItemValue::Locator(t) => t.clone(),
|
|
ItemValue::Binary(b) => format!("<{} bytes>", b.len()),
|
|
};
|
|
Some(TagEntry {
|
|
key: format!("{:?}", item.key()),
|
|
value,
|
|
})
|
|
})
|
|
.collect();
|
|
|
|
Ok(Some(entries))
|
|
}
|
|
|
|
/// Extract the artist name from a music file.
|
|
pub fn read_artist_name(path: &Path) -> 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(ItemKey::TrackArtist).map(String::from))
|
|
}
|
|
|
|
/// Extract the MusicBrainz artist ID from a music file.
|
|
pub fn read_artist_mbid(path: &Path) -> 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(ItemKey::MusicBrainzArtistId).map(String::from))
|
|
}
|
|
|
|
/// Extract the MusicBrainz recording ID from a music file.
|
|
pub fn read_track_mbid(path: &Path) -> 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(ItemKey::MusicBrainzRecordingId).map(String::from))
|
|
}
|