Skip to content

Commit

Permalink
Fix remaining issues (#21)
Browse files Browse the repository at this point in the history
* Remove `unwrap` in `Tag::read_from_path`

closes: #7

* Fix `Id3v2Tag::{*year}` methods

closes: #9

* Fix unused `Result` in `Tag` doc example

* Reorder `FlagTag` and `Mp4Tag` impls to match `AudioTagEdit`

* Change `Tag::read_from_path` return type to `Result<Box<dyn AudioTag + Send + Sync>>`

closes: #8

* Fix doc test

* Fix typos

* Bump versions

* fmt
  • Loading branch information
Serial-ATA committed Aug 2, 2022
1 parent ccb3df0 commit 2fa3f6c
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 96 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "audiotags"
version = "0.4.1"
version = "0.5.0"
authors = ["Tianyi <ShiTianyi2001@outlook.com>", "Pierre de la Martinière <pierre.de.la.martiniere@gmail.com>"]
edition = "2021"
description = "Unified IO for different types of audio metadata"
Expand All @@ -15,7 +15,7 @@ id3 = "1.1.0"
mp4ameta = "0.11.0"
metaflac = "0.2.5"
thiserror = "1.0.31"
audiotags-dev-macro = {path = "./audiotags-dev-macro", version = "0.1.4"}
audiotags-dev-macro = {path = "./audiotags-dev-macro", version = "0.2.0"}

[dev-dependencies]
tempfile = "3.3.0"
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![Crate](https://img.shields.io/crates/l/audiotags.svg)](https://crates.io/crates/audiotags)
[![Documentation](https://docs.rs/audiotags/badge.svg)](https://docs.rs/audiotags/)

This crate makes it easier to parse, convert and write metadata (a.k.a tag) in audio files of different file types.
This crate makes it easier to parse, convert and write metadata (a.k.a. tag) in audio files of different file types.

This crate aims to provide a unified trait for parsers and writers of different audio file formats.
This means that you can parse tags in mp3, flac, and m4a files with a single function: `Tag::default().
Expand All @@ -25,8 +25,8 @@ by specialized libraries. **audiotags** is not making additional unnecessary cop

### Supported Formats

| File Fomat | Metadata Format | backend |
| ------------- | --------------------- | ----------------------------------------------------------- |
| File Format | Metadata Format | backend |
|---------------|-----------------------|-------------------------------------------------------------|
| `mp3` | id3v2.4 | [**id3**](https://github.com/polyfloyd/rust-id3) |
| `m4a/mp4/...` | MPEG-4 audio metadata | [**mp4ameta**](https://github.com/Saecki/rust-mp4ameta) |
| `flac` | Vorbis comment | [**metaflac**](https://github.com/jameshurst/rust-metaflac) |
Expand Down
4 changes: 2 additions & 2 deletions audiotags-dev-macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "audiotags-dev-macro"
version = "0.1.4"
version = "0.2.0"
authors = ["Tianyi <ShiTianyi2001@outlook.com>"]
edition = "2018"
edition = "2021"
description = "macros used during the development of audiotags"
license = "MIT"
repository = "https://github.com/TianyiShi2001/audiotags"
Expand Down
8 changes: 4 additions & 4 deletions audiotags-dev-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ macro_rules! impl_tag {
}

// From dyn AudioTag to wrapper (any type)
impl From<Box<dyn AudioTag>> for $tag {
fn from(inp: Box<dyn AudioTag>) -> Self {
impl From<Box<dyn AudioTag + Send + Sync>> for $tag {
fn from(inp: Box<dyn AudioTag + Send + Sync>) -> Self {
let mut inp = inp;
if let Some(t_refmut) = inp.to_any_mut().downcast_mut::<$tag>() {
let t = std::mem::replace(t_refmut, $tag::new()); // TODO: can we avoid creating the dummy tag?
Expand All @@ -85,8 +85,8 @@ macro_rules! impl_tag {
}
}
// From dyn AudioTag to inner (any type)
impl std::convert::From<Box<dyn AudioTag>> for $inner {
fn from(inp: Box<dyn AudioTag>) -> Self {
impl std::convert::From<Box<dyn AudioTag + Send + Sync>> for $inner {
fn from(inp: Box<dyn AudioTag + Send + Sync>) -> Self {
let t: $tag = inp.into();
t.into()
}
Expand Down
65 changes: 32 additions & 33 deletions src/components/flac_tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,19 @@ impl AudioTagEdit for FlacTag {
fn set_title(&mut self, title: &str) {
self.set_first("TITLE", title);
}
fn remove_title(&mut self) {
self.remove("TITLE");
}

fn artist(&self) -> Option<&str> {
self.get_first("ARTIST")
}
fn set_artist(&mut self, artist: &str) {
self.set_first("ARTIST", artist)
}
fn remove_artist(&mut self) {
self.remove("ARTIST");
}

fn year(&self) -> Option<i32> {
if let Some(Ok(y)) = self
Expand All @@ -113,6 +119,10 @@ impl AudioTagEdit for FlacTag {
self.set_first("DATE", &year.to_string());
self.set_first("YEAR", &year.to_string());
}
fn remove_year(&mut self) {
self.remove("YEAR");
self.remove("DATE");
}

fn duration(&self) -> Option<f64> {
self.inner
Expand All @@ -126,13 +136,19 @@ impl AudioTagEdit for FlacTag {
fn set_album_title(&mut self, title: &str) {
self.set_first("ALBUM", title)
}
fn remove_album_title(&mut self) {
self.remove("ALBUM");
}

fn album_artist(&self) -> Option<&str> {
self.get_first("ALBUMARTIST")
}
fn set_album_artist(&mut self, v: &str) {
self.set_first("ALBUMARTIST", v)
}
fn remove_album_artist(&mut self) {
self.remove("ALBUMARTIST");
}

fn album_cover(&self) -> Option<Picture> {
self.inner
Expand All @@ -152,6 +168,10 @@ impl AudioTagEdit for FlacTag {
self.inner
.add_picture(mime, picture_type, (cover.data).to_owned());
}
fn remove_album_cover(&mut self) {
self.inner
.remove_picture_type(metaflac::block::PictureType::CoverFront)
}

fn composer(&self) -> Option<&str> {
self.get_first("COMPOSER")
Expand All @@ -173,6 +193,9 @@ impl AudioTagEdit for FlacTag {
fn set_track_number(&mut self, v: u16) {
self.set_first("TRACKNUMBER", &v.to_string())
}
fn remove_track_number(&mut self) {
self.remove("TRACKNUMBER");
}

// ! not standard
fn total_tracks(&self) -> Option<u16> {
Expand All @@ -185,6 +208,9 @@ impl AudioTagEdit for FlacTag {
fn set_total_tracks(&mut self, v: u16) {
self.set_first("TOTALTRACKS", &v.to_string())
}
fn remove_total_tracks(&mut self) {
self.remove("TOTALTRACKS");
}

fn disc_number(&self) -> Option<u16> {
if let Some(Ok(n)) = self.get_first("DISCNUMBER").map(|x| x.parse::<u16>()) {
Expand All @@ -196,6 +222,9 @@ impl AudioTagEdit for FlacTag {
fn set_disc_number(&mut self, v: u16) {
self.set_first("DISCNUMBER", &v.to_string())
}
fn remove_disc_number(&mut self) {
self.remove("DISCNUMBER");
}

// ! not standard
fn total_discs(&self) -> Option<u16> {
Expand All @@ -208,46 +237,16 @@ impl AudioTagEdit for FlacTag {
fn set_total_discs(&mut self, v: u16) {
self.set_first("TOTALDISCS", &v.to_string())
}
fn remove_total_discs(&mut self) {
self.remove("TOTALDISCS");
}

fn genre(&self) -> Option<&str> {
self.get_first("GENRE")
}
fn set_genre(&mut self, v: &str) {
self.set_first("GENRE", v);
}

fn remove_title(&mut self) {
self.remove("TITLE");
}
fn remove_artist(&mut self) {
self.remove("ARTIST");
}
fn remove_year(&mut self) {
self.remove("YEAR");
self.remove("DATE");
}
fn remove_album_title(&mut self) {
self.remove("ALBUM");
}
fn remove_album_artist(&mut self) {
self.remove("ALBUMARTIST");
}
fn remove_album_cover(&mut self) {
self.inner
.remove_picture_type(metaflac::block::PictureType::CoverFront)
}
fn remove_track_number(&mut self) {
self.remove("TRACKNUMBER");
}
fn remove_total_tracks(&mut self) {
self.remove("TOTALTRACKS");
}
fn remove_disc_number(&mut self) {
self.remove("DISCNUMBER");
}
fn remove_total_discs(&mut self) {
self.remove("TOTALDISCS");
}
fn remove_genre(&mut self) {
self.remove("GENRE");
}
Expand Down
31 changes: 28 additions & 3 deletions src/components/id3_tag.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::*;
use id3::{self, Content, Frame, TagLike};
use id3::{self, Content, Frame, TagLike, Timestamp, Version};

pub use id3::Tag as Id3v2InnerTag;

Expand Down Expand Up @@ -104,12 +104,37 @@ impl AudioTagEdit for Id3v2Tag {
}

fn year(&self) -> Option<i32> {
self.inner.year()
if self.inner.version() == Version::Id3v23 {
if let ret @ Some(_) = self.inner.year() {
return ret;
}
}

self.inner.date_recorded().map(|timestamp| timestamp.year)
}
fn set_year(&mut self, year: i32) {
self.inner.set_year(year)
if self.inner.version() == Version::Id3v23 {
self.inner.set_year(year);
return;
}

if let Some(mut timestamp) = self.inner.date_recorded() {
timestamp.year = year;
self.inner.set_date_recorded(timestamp);
return;
}

self.inner.set_date_recorded(Timestamp {
year,
month: None,
day: None,
hour: None,
minute: None,
second: None,
});
}
fn remove_year(&mut self) {
self.inner.remove_date_recorded();
self.inner.remove_year();
}
fn duration(&self) -> Option<f64> {
Expand Down
Loading

0 comments on commit 2fa3f6c

Please sign in to comment.