This commit is contained in:
Serial 2021-08-24 23:35:28 -04:00
parent b6aa1595e5
commit 2c3a041807
13 changed files with 61 additions and 79 deletions

View file

@ -1,10 +1,10 @@
use criterion::{criterion_group, criterion_main, Criterion};
use lofty::Tag;
use lofty::Probe;
macro_rules! test_read {
($function:ident, $path:expr) => {
fn $function() {
Tag::new().read_from_path_signature($path).unwrap();
Probe::new().read_from_path($path).unwrap();
}
};
}
@ -12,18 +12,18 @@ macro_rules! test_read {
test_read!(read_aiff, "tests/assets/a_text.aiff");
test_read!(read_ape, "tests/assets/a.ape");
test_read!(read_flac, "tests/assets/a.flac");
test_read!(read_m4a, "tests/assets/a.m4a");
//test_read!(read_m4a, "tests/assets/a.m4a"); TODO
test_read!(read_mp3, "tests/assets/a.mp3");
test_read!(read_vorbis, "tests/assets/a.ogg");
test_read!(read_opus, "tests/assets/a.opus");
test_read!(read_riff, "tests/assets/a.wav");
fn bench_sig(c: &mut Criterion) {
let mut g = c.benchmark_group("From signature");
let mut g = c.benchmark_group("File reading");
g.bench_function("AIFF", |b| b.iter(read_aiff));
g.bench_function("APE", |b| b.iter(read_ape));
g.bench_function("FLAC", |b| b.iter(read_flac));
g.bench_function("MP4", |b| b.iter(read_m4a));
// g.bench_function("MP4", |b| b.iter(read_m4a));
g.bench_function("MP3", |b| b.iter(read_mp3));
g.bench_function("VORBIS", |b| b.iter(read_vorbis));
g.bench_function("OPUS", |b| b.iter(read_opus));

View file

@ -1,32 +0,0 @@
use criterion::{criterion_group, criterion_main, Criterion};
use lofty::Tag;
macro_rules! test_read {
($function:ident, $path:expr) => {
fn $function() {
Tag::new().read_from_path($path).unwrap();
}
};
}
test_read!(read_ape, "tests/assets/a.ape");
test_read!(read_flac, "tests/assets/a.flac");
test_read!(read_m4a, "tests/assets/a.m4a");
test_read!(read_mp3, "tests/assets/a.mp3");
test_read!(read_vorbis, "tests/assets/a.ogg");
test_read!(read_opus, "tests/assets/a.opus");
test_read!(read_riff, "tests/assets/a-id3.wav");
fn bench_ext(c: &mut Criterion) {
let mut g = c.benchmark_group("From extension");
g.bench_function("APE", |b| b.iter(read_ape));
g.bench_function("FLAC", |b| b.iter(read_flac));
g.bench_function("MP4", |b| b.iter(read_m4a));
g.bench_function("MP3", |b| b.iter(read_mp3));
g.bench_function("VORBIS", |b| b.iter(read_vorbis));
g.bench_function("OPUS", |b| b.iter(read_opus));
g.bench_function("RIFF", |b| b.iter(read_riff));
}
criterion_group!(benches, bench_ext);
criterion_main!(benches);

View file

@ -121,7 +121,9 @@
clippy::let_underscore_drop,
clippy::match_wildcard_for_single_variants,
clippy::semicolon_if_nothing_returned,
clippy::used_underscore_binding
clippy::used_underscore_binding,
clippy::new_without_default,
clippy::unused_self
)]
pub use crate::error::{LoftyError, Result};

View file

@ -5,7 +5,7 @@ pub(crate) mod tag;
pub(crate) mod write;
use crate::types::file::AudioFile;
use crate::{FileProperties, FileType, Result, Tag, TagType, TaggedFile};
use crate::{FileProperties, Result, Tag, TagType};
use std::io::{Read, Seek};

View file

@ -5,6 +5,7 @@ use crate::files::ApeFile;
use crate::logic::id3::find_lyrics3v2;
use crate::logic::id3::v1::find_id3v1;
use crate::logic::id3::v2::find_id3v2;
use crate::logic::id3::v2::read::parse_id3v2;
use crate::{FileProperties, LoftyError, Result};
use std::io::{Read, Seek, SeekFrom};
@ -51,6 +52,14 @@ where
// ID3v2 tags are unsupported in APE files, but still possible
if let Some(id3v2) = find_id3v2(data, true)? {
stream_len -= id3v2.len() as u64;
let id3v2 = parse_id3v2(&mut &*id3v2)?;
// Skip over the footer
if id3v2.flags().footer {
data.seek(SeekFrom::Current(10))?;
}
ape_file.id3v2 = Some(id3v2)
}

View file

@ -1,6 +1,6 @@
use crate::logic::id3::v2::read::parse_id3v2;
use crate::types::file::AudioFile;
use crate::{FileProperties, FileType, LoftyError, Result, TagType, TaggedFile};
use crate::{FileProperties, LoftyError, Result, TagType};
use crate::{ItemKey, ItemValue, Tag, TagItem};
use std::io::{Read, Seek, SeekFrom};

View file

@ -3,7 +3,7 @@ pub(crate) mod header;
pub(crate) mod read;
use crate::types::file::AudioFile;
use crate::{FileProperties, FileType, Result, Tag, TagType, TaggedFile};
use crate::{FileProperties, Result, Tag, TagType};
use std::io::{Read, Seek};

View file

@ -3,7 +3,6 @@ use super::write::create_comments;
use crate::error::{LoftyError, Result};
use crate::picture::Picture;
use crate::types::file::AudioFile;
use crate::types::file::{FileType, TaggedFile};
use crate::types::properties::FileProperties;
use crate::types::tag::{Tag, TagType};

View file

@ -2,7 +2,6 @@ use super::find_last_page;
use crate::error::{LoftyError, Result};
use crate::logic::ogg::constants::{OPUSHEAD, OPUSTAGS};
use crate::types::file::AudioFile;
use crate::types::file::{FileType, TaggedFile};
use crate::types::properties::FileProperties;
use crate::types::tag::{Tag, TagType};

View file

@ -2,7 +2,6 @@ use super::find_last_page;
use crate::error::{LoftyError, Result};
use crate::logic::ogg::constants::{VORBIS_COMMENT_HEAD, VORBIS_IDENT_HEAD, VORBIS_SETUP_HEAD};
use crate::types::file::AudioFile;
use crate::types::file::{FileType, TaggedFile};
use crate::types::properties::FileProperties;
use crate::types::tag::{Tag, TagType};

View file

@ -1,4 +1,10 @@
use crate::files::*;
use crate::logic::iff::aiff::AiffFile;
use crate::logic::ape::ApeFile;
use crate::logic::ogg::flac::FlacFile;
use crate::logic::mpeg::MpegFile;
use crate::logic::ogg::opus::OpusFile;
use crate::logic::ogg::vorbis::VorbisFile;
use crate::logic::iff::wav::WavFile;
use crate::types::file::AudioFile;
use crate::{FileType, LoftyError, Result, TaggedFile};

View file

@ -53,7 +53,22 @@ pub enum MimeType {
None,
}
impl ToString for MimeType {
fn to_string(&self) -> String {
match self {
MimeType::Jpeg => "image/jpeg".to_string(),
MimeType::Png => "image/png".to_string(),
MimeType::Tiff => "image/tiff".to_string(),
MimeType::Bmp => "image/bmp".to_string(),
MimeType::Gif => "image/gif".to_string(),
MimeType::Unknown(unknown) => unknown.clone(),
MimeType::None => String::new(),
}
}
}
impl MimeType {
#[allow(clippy::should_implement_trait)]
/// Get a MimeType from a string
pub fn from_str(mime_type: &str) -> Self {
match &*mime_type.to_lowercase() {
@ -79,19 +94,6 @@ impl MimeType {
MimeType::None => "",
}
}
/// Get a String from a MimeType
pub fn to_string(&self) -> String {
match self {
MimeType::Jpeg => "image/jpeg".to_string(),
MimeType::Png => "image/png".to_string(),
MimeType::Tiff => "image/tiff".to_string(),
MimeType::Bmp => "image/bmp".to_string(),
MimeType::Gif => "image/gif".to_string(),
MimeType::Unknown(unknown) => unknown.to_owned(),
MimeType::None => String::new(),
}
}
}
/// The picture type
@ -150,7 +152,7 @@ impl PictureType {
Self::Illustration => 18,
Self::BandLogo => 19,
Self::PublisherLogo => 20,
Self::Undefined(i) => u8::from(i.to_owned()),
Self::Undefined(i) => *i,
}
}
@ -294,6 +296,7 @@ impl Picture {
}
#[cfg(feature = "id3v2")]
#[allow(clippy::single_match_else)]
/// Convert a [`Picture`] to a ID3v2 A/PIC byte Vec
///
/// NOTE: This does not include the frame header
@ -320,8 +323,8 @@ impl Picture {
let mut data = vec![self.text_encoding as u8];
data.write_all(format.as_bytes());
data.write_u8(self.pic_type.as_u8());
data.write_all(format.as_bytes())?;
data.write_u8(self.pic_type.as_u8())?;
if let Some(description) = &self.description {
data.write_all(&*crate::logic::id3::v2::util::text_utils::encode_text(
@ -332,11 +335,11 @@ impl Picture {
}
data.write_u8(0)?;
data.write_all(&*self.data);
data.write_all(&*self.data)?;
let size = data.len() - 6;
if size as u64 > u32::MAX as u64 {
if size as u64 > u64::from(u32::MAX) {
return Err(LoftyError::TooMuchData);
}
@ -367,7 +370,7 @@ impl Picture {
let size = data.len();
if size as u64 > u32::MAX as u64 {
if size as u64 > u64::from(u32::MAX) {
return Err(LoftyError::TooMuchData);
}
@ -377,6 +380,7 @@ impl Picture {
}
#[cfg(feature = "id3v2")]
#[allow(clippy::single_match_else)]
/// Get a [`Picture`] from ID3v2 A/PIC bytes:
///
/// NOTE: This expects the frame header to have already been skipped
@ -409,7 +413,7 @@ impl Picture {
encoding,
true,
)?
.map(|s| Cow::from(s));
.map(Cow::from);
let mut data = Vec::new();
cursor.read_to_end(&mut data)?;
@ -429,16 +433,12 @@ impl Picture {
})
},
_ => {
let mime_type = if let Some(mime_type) =
crate::logic::id3::v2::util::text_utils::decode_text(
&mut cursor,
encoding,
true,
)? {
MimeType::from_str(&*mime_type)
} else {
MimeType::None
};
let mime_type = (crate::logic::id3::v2::util::text_utils::decode_text(
&mut cursor,
encoding,
true,
)?)
.map_or(MimeType::None, |mime_type| MimeType::from_str(&*mime_type));
let picture_type = PictureType::from_u8(cursor.read_u8()?);
let description = crate::logic::id3::v2::util::text_utils::decode_text(
@ -446,7 +446,7 @@ impl Picture {
encoding,
true,
)?
.map(|s| Cow::from(s));
.map(Cow::from);
let mut data = Vec::new();
cursor.read_to_end(&mut data)?;
@ -468,7 +468,7 @@ impl Picture {
};
}
return Err(LoftyError::NotAPicture);
Err(LoftyError::NotAPicture)
}
#[cfg(feature = "vorbis_comments")]
@ -481,7 +481,7 @@ impl Picture {
pub fn as_flac_bytes(&self) -> String {
let mut data = Vec::<u8>::new();
let picture_type = (self.pic_type.as_u8() as u32).to_be_bytes();
let picture_type = u32::from(self.pic_type.as_u8()).to_be_bytes();
let mime_str = self.mime_type.to_string();
let mime_len = mime_str.len() as u32;

View file

@ -235,7 +235,7 @@ impl Tag {
/// Retain tag items based on the predicate
///
/// See [`Vec::retain`](std::vec::Vec::retain)
pub fn retain<F>(&mut self, mut f: F)
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&TagItem) -> bool,
{