Skip to content

Commit

Permalink
Feat/add full date capabilities (#34)
Browse files Browse the repository at this point in the history
* Remove unused import

* Add date_released, original_date_released, and date_recorded

* Remove DATE as well as YEAR

* Generify 'date' concept to singular generic `date` property

* Generify to `date` on AudioTagEdit

* Remove `date_recorded` as well as `year`
  • Loading branch information
BSteffaniak authored Nov 22, 2023
1 parent 46c7dcf commit e4ee5c9
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 31 deletions.
8 changes: 8 additions & 0 deletions src/anytag.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use crate::*;
use id3::Timestamp;

#[derive(Default)]
pub struct AnyTag<'a> {
pub config: Config,
pub title: Option<&'a str>,
pub artists: Option<Vec<&'a str>>,
pub date: Option<Timestamp>,
pub year: Option<i32>,
pub duration: Option<f64>,
pub album_title: Option<&'a str>,
Expand Down Expand Up @@ -39,6 +41,12 @@ impl<'a> AnyTag<'a> {
self.artists.as_deref()
}
// set_artists; add_artist
pub fn date(&self) -> Option<Timestamp> {
self.date
}
pub fn set_date(&mut self, date: Timestamp) {
self.date = Some(date);
}
pub fn year(&self) -> Option<i32> {
self.year
}
Expand Down
27 changes: 23 additions & 4 deletions src/components/flac_tag.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::*;
use id3::Timestamp;
use metaflac;
use std::str::FromStr;

pub use metaflac::Tag as FlacInnerTag;

Expand All @@ -14,6 +16,9 @@ impl<'a> From<AnyTag<'a>> for FlacTag {
if let Some(v) = inp.artists_as_string() {
t.set_artist(&v)
}
if let Some(v) = inp.date {
t.set_date(v)
}
if let Some(v) = inp.year {
t.set_year(v)
}
Expand Down Expand Up @@ -44,6 +49,7 @@ impl<'a> From<&'a FlacTag> for AnyTag<'a> {
let tag = Self {
title: inp.title(),
artists: inp.artists(),
date: inp.date(),
year: inp.year(),
duration: inp.duration(),
album_title: inp.album_title(),
Expand Down Expand Up @@ -104,20 +110,33 @@ impl AudioTagEdit for FlacTag {
self.remove("ARTIST");
}

fn date(&self) -> Option<Timestamp> {
if let Some(Ok(timestamp)) = self.get_first("DATE").map(Timestamp::from_str) {
Some(timestamp)
} else {
None
}
}
fn set_date(&mut self, date: Timestamp) {
self.set_first("DATE", &date.to_string());
}
fn remove_date(&mut self) {
self.remove("DATE");
}

fn year(&self) -> Option<i32> {
if let Some(Ok(y)) = self
if let Some(Ok(y)) = self.get_first("YEAR").map(|s| s.parse::<i32>()) {
Some(y)
} else if let Some(Ok(y)) = self
.get_first("DATE")
.map(|s| s.chars().take(4).collect::<String>().parse::<i32>())
{
Some(y)
} else if let Some(Ok(y)) = self.get_first("YEAR").map(|s| s.parse::<i32>()) {
Some(y)
} else {
None
}
}
fn set_year(&mut self, year: i32) {
self.set_first("DATE", &year.to_string());
self.set_first("YEAR", &year.to_string());
}
fn remove_year(&mut self) {
Expand Down
44 changes: 17 additions & 27 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, Timestamp, Version};
use id3::{self, Content, Frame, TagLike, Timestamp};

pub use id3::Tag as Id3v2InnerTag;

Expand All @@ -12,6 +12,7 @@ impl<'a> From<&'a Id3v2Tag> for AnyTag<'a> {

title: inp.title(),
artists: inp.artists(),
date: inp.date(),
year: inp.year(),
duration: inp.inner.duration().map(f64::from),
album_title: inp.album_title(),
Expand Down Expand Up @@ -40,6 +41,9 @@ impl<'a> From<AnyTag<'a>> for Id3v2Tag {
if let Some(v) = inp.artists_as_string() {
t.set_artist(&v)
}
if let Some(v) = inp.date() {
t.set_date_recorded(v)
}
if let Some(v) = inp.year {
t.set_year(v)
}
Expand Down Expand Up @@ -102,35 +106,21 @@ impl AudioTagEdit for Id3v2Tag {
self.inner.remove_artist();
}

fn year(&self) -> Option<i32> {
if self.inner.version() == Version::Id3v23 {
if let ret @ Some(_) = self.inner.year() {
return ret;
}
}
fn date(&self) -> Option<Timestamp> {
self.inner.date_recorded()
}
fn set_date(&mut self, timestamp: Timestamp) {
self.inner.set_date_recorded(timestamp)
}
fn remove_date(&mut self) {
self.inner.remove_date_recorded()
}

self.inner.date_recorded().map(|timestamp| timestamp.year)
fn year(&self) -> Option<i32> {
self.inner.year()
}
fn set_year(&mut self, year: i32) {
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,
});
self.inner.set_year(year);
}
fn remove_year(&mut self) {
self.inner.remove_date_recorded();
Expand Down
18 changes: 18 additions & 0 deletions src/components/mp4_tag.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::*;
use id3::Timestamp;
use mp4ameta::{self, ImgFmt};
use std::str::FromStr;

pub use mp4ameta::Tag as Mp4InnerTag;

Expand All @@ -9,6 +11,7 @@ impl<'a> From<&'a Mp4Tag> for AnyTag<'a> {
fn from(inp: &'a Mp4Tag) -> Self {
let title = inp.title();
let artists = inp.artists().map(|i| i.into_iter().collect::<Vec<_>>());
let date = inp.date();
let year = inp.year();
let duration = inp.duration();
let album_title = inp.album_title();
Expand All @@ -29,6 +32,7 @@ impl<'a> From<&'a Mp4Tag> for AnyTag<'a> {
config: inp.config,
title,
artists,
date,
year,
duration,
album_title,
Expand Down Expand Up @@ -137,6 +141,20 @@ impl AudioTagEdit for Mp4Tag {
self.inner.add_artist(v);
}

fn date(&self) -> Option<Timestamp> {
if let Some(Ok(date)) = self.inner.year().map(Timestamp::from_str) {
Some(date)
} else {
None
}
}
fn set_date(&mut self, date: Timestamp) {
self.inner.set_year(date.to_string())
}
fn remove_date(&mut self) {
self.inner.remove_year()
}

fn year(&self) -> Option<i32> {
self.inner.year().and_then(|x| str::parse(x).ok())
}
Expand Down
5 changes: 5 additions & 0 deletions src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::*;
use id3::Timestamp;

pub trait AudioTag: AudioTagEdit + AudioTagWrite + ToAnyTag {}

Expand Down Expand Up @@ -31,6 +32,10 @@ pub trait AudioTagEdit: AudioTagConfig {
self.set_artist(artist);
}

fn date(&self) -> Option<Timestamp>;
fn set_date(&mut self, date: Timestamp);
fn remove_date(&mut self);

fn year(&self) -> Option<i32>;
fn set_year(&mut self, year: i32);
fn remove_year(&mut self);
Expand Down
11 changes: 11 additions & 0 deletions tests/io.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use audiotags::{MimeType, Picture, Tag};
use id3::Timestamp;
use std::ffi::OsString;
use std::fs;
use std::path::Path;
use std::str::FromStr;
use tempfile::Builder;

macro_rules! test_file {
Expand All @@ -28,6 +30,15 @@ macro_rules! test_file {
assert!(tags.artist().is_none());
tags.remove_artist();

tags.set_date(Timestamp::from_str("2020-05-22").unwrap());
assert_eq!(
tags.date(),
Some(Timestamp::from_str("2020-05-22").unwrap())
);
tags.remove_date();
assert!(tags.date().is_none());
tags.remove_date();

tags.set_year(2020);
assert_eq!(tags.year(), Some(2020));
tags.remove_year();
Expand Down

0 comments on commit e4ee5c9

Please sign in to comment.