mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-11-10 06:34:18 +00:00
Allow removing ID3v2 tags from FLAC and APE
This commit is contained in:
parent
b41cd32677
commit
e2d0978ce1
9 changed files with 53 additions and 10 deletions
|
@ -27,6 +27,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- `lofty::read_from` will now wrap the `File` in a `BufReader`
|
||||
- **FLAC**: FLAC now has its own module at `lofty::flac`
|
||||
- **ID3v2**: `FrameValue` is now `#[non_exhaustive]`
|
||||
- `TagType::remove_from` now works for ID3v2 tags in APE and FLAC files
|
||||
- This previously verified that the `FileType` supported the tag. It now has special exceptions for these formats to
|
||||
allow stripping out these unsupported tags
|
||||
|
||||
### Fixed
|
||||
- **MP4**: Non-full `meta` atoms are now properly handled.
|
||||
|
|
|
@ -3,6 +3,8 @@ use crate::ape;
|
|||
use crate::error::{ErrorKind, LoftyError, Result};
|
||||
#[cfg(feature = "id3v1")]
|
||||
use crate::id3::v1;
|
||||
#[cfg(feature = "id3v2")]
|
||||
use crate::id3::v2;
|
||||
#[allow(unused_imports)]
|
||||
use crate::tag::{Tag, TagType};
|
||||
|
||||
|
@ -17,6 +19,9 @@ pub(crate) fn write_to(data: &mut File, tag: &Tag) -> Result<()> {
|
|||
items: ape::tag::tagitems_into_ape(tag.items()),
|
||||
}
|
||||
.write_to(data),
|
||||
// This tag can *only* be removed in this format
|
||||
#[cfg(feature = "id3v2")]
|
||||
TagType::Id3v2 => v2::tag::Id3v2TagRef::empty().write_to(data),
|
||||
#[cfg(feature = "id3v1")]
|
||||
TagType::Id3v1 => Into::<v1::tag::Id3v1TagRef<'_>>::into(tag).write_to(data),
|
||||
_ => Err(LoftyError::new(ErrorKind::UnsupportedTag)),
|
||||
|
|
|
@ -17,7 +17,7 @@ use crate::id3::v2::tag::Id3v2Tag;
|
|||
#[cfg(feature = "vorbis_comments")]
|
||||
use crate::ogg::VorbisComments;
|
||||
use crate::properties::FileProperties;
|
||||
use crate::tag::TagType;
|
||||
use crate::tag::{Tag, TagType};
|
||||
|
||||
use std::io::{Read, Seek};
|
||||
|
||||
|
@ -44,15 +44,21 @@ pub struct FlacFile {
|
|||
}
|
||||
|
||||
impl From<FlacFile> for TaggedFile {
|
||||
#[allow(clippy::vec_init_then_push)]
|
||||
fn from(input: FlacFile) -> Self {
|
||||
let mut tags = Vec::<Option<Tag>>::with_capacity(2);
|
||||
|
||||
#[cfg(feature = "vorbis_comments")]
|
||||
tags.push(input.vorbis_comments.map(Into::into));
|
||||
#[cfg(feature = "id3v2")]
|
||||
tags.push(input.id3v2_tag.map(Into::into));
|
||||
|
||||
Self {
|
||||
ty: FileType::FLAC,
|
||||
properties: input.properties,
|
||||
#[cfg(feature = "vorbis_comments")]
|
||||
tags: input
|
||||
.vorbis_comments
|
||||
.map_or_else(Vec::new, |t| vec![t.into()]),
|
||||
#[cfg(not(feature = "vorbis_comments"))]
|
||||
#[cfg(any(feature = "vorbis_comments", feature = "id3v2"))]
|
||||
tags: tags.into_iter().flatten().collect(),
|
||||
#[cfg(not(any(feature = "vorbis_comments", feature = "id3v2")))]
|
||||
tags: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -428,6 +428,15 @@ pub(crate) struct Id3v2TagRef<'a, I: Iterator<Item = FrameRef<'a>> + 'a> {
|
|||
pub(crate) frames: I,
|
||||
}
|
||||
|
||||
impl<'a> Id3v2TagRef<'a, std::iter::Empty<FrameRef<'a>>> {
|
||||
pub(crate) fn empty() -> Self {
|
||||
Self {
|
||||
flags: Id3v2TagFlags::default(),
|
||||
frames: std::iter::empty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create an iterator of FrameRef from a Tag's items for Id3v2TagRef::new
|
||||
pub(crate) fn tag_frames(tag: &Tag) -> impl Iterator<Item = FrameRef<'_>> + '_ {
|
||||
let items = tag
|
||||
|
|
|
@ -41,7 +41,7 @@ pub(crate) fn write_id3v2<'a, I: Iterator<Item = FrameRef<'a>> + 'a>(
|
|||
let data = probe.into_inner();
|
||||
|
||||
match file_type {
|
||||
Some(FileType::APE | FileType::MP3) => {},
|
||||
Some(FileType::APE | FileType::MP3 | FileType::FLAC) => {},
|
||||
// Formats such as WAV and AIFF store the ID3v2 tag in an 'ID3 ' chunk rather than at the beginning of the file
|
||||
Some(FileType::WAV) => {
|
||||
tag.flags.footer = false;
|
||||
|
@ -77,6 +77,7 @@ pub(super) fn create_tag<'a, I: Iterator<Item = FrameRef<'a>> + 'a>(
|
|||
let frames = &mut tag.frames;
|
||||
let mut peek = frames.peekable();
|
||||
|
||||
// We are stripping the tag
|
||||
if peek.peek().is_none() {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ pub(in crate) fn write_to(file: &mut File, tag: &Tag, file_type: FileType) -> Re
|
|||
pictures,
|
||||
};
|
||||
|
||||
if let FileType::FLAC = file_type {
|
||||
if file_type == FileType::FLAC {
|
||||
return flac::write::write_to(file, &mut comments_ref);
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,11 @@ pub(in crate) fn write_to(file: &mut File, tag: &Tag, file_type: FileType) -> Re
|
|||
|
||||
write(file, &mut comments_ref, format)
|
||||
},
|
||||
#[cfg(feature = "id3v2")]
|
||||
TagType::Id3v2 if file_type == FileType::FLAC => {
|
||||
// This tag can *only* be removed in this format
|
||||
crate::id3::v2::tag::Id3v2TagRef::empty().write_to(file)
|
||||
},
|
||||
_ => Err(LoftyError::new(ErrorKind::UnsupportedTag)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ pub(crate) mod item;
|
|||
pub(crate) mod utils;
|
||||
|
||||
use crate::error::{ErrorKind, LoftyError, Result};
|
||||
use crate::file::FileType;
|
||||
use crate::picture::{Picture, PictureType};
|
||||
use crate::probe::Probe;
|
||||
use crate::traits::{Accessor, TagExt};
|
||||
|
@ -448,7 +449,10 @@ impl TagType {
|
|||
None => return Err(LoftyError::new(ErrorKind::UnknownFormat)),
|
||||
};
|
||||
|
||||
if !file_type.supports_tag_type(*self) {
|
||||
let special_exceptions =
|
||||
(file_type == FileType::APE || file_type == FileType::FLAC) && *self == TagType::Id3v2;
|
||||
|
||||
if !special_exceptions && !file_type.supports_tag_type(*self) {
|
||||
return Err(LoftyError::new(ErrorKind::UnsupportedTag));
|
||||
}
|
||||
|
||||
|
|
|
@ -52,3 +52,8 @@ fn remove_ape() {
|
|||
fn remove_id3v1() {
|
||||
crate::remove_tag!("tests/files/assets/minimal/full_test.ape", TagType::Id3v1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_id3v2() {
|
||||
crate::remove_tag!("tests/files/assets/minimal/full_test.ape", TagType::Id3v2);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ fn flac_write() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn flac_remove() {
|
||||
fn flac_remove_vorbis_comments() {
|
||||
crate::remove_tag!(
|
||||
"tests/files/assets/minimal/full_test.flac",
|
||||
TagType::VorbisComments
|
||||
|
@ -135,3 +135,8 @@ fn flac_with_id3v2() {
|
|||
|
||||
assert!(flac_file.vorbis_comments().is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flac_remove_id3v2() {
|
||||
crate::remove_tag!("tests/files/assets/flac_with_id3v2.flac", TagType::Id3v2);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue