Fully document the crate

Signed-off-by: Serial <69764315+Serial-ATA@users.noreply.github.com>
This commit is contained in:
Serial 2021-05-16 00:39:19 -04:00
parent 42d0069bf0
commit 83a0f84b9e
12 changed files with 101 additions and 10 deletions

View file

@ -16,6 +16,7 @@ use std::time::Duration;
impl_tag!(ApeTag, ApeInnerTag, TagType::Ape);
impl ApeTag {
#[allow(missing_docs)]
#[allow(clippy::missing_errors_doc)]
pub fn read_from_path<P>(path: P) -> Result<Self>
where

View file

@ -20,6 +20,7 @@ use std::time::Duration;
impl_tag!(Id3v2Tag, Id3v2InnerTag, TagType::Id3v2(Id3Format::Default));
impl Id3v2Tag {
#[allow(missing_docs)]
#[allow(clippy::missing_errors_doc)]
pub fn read_from_path<P>(path: P, format: &Id3Format) -> Result<Self>
where
@ -59,8 +60,8 @@ impl std::convert::TryFrom<id3::frame::Picture> for Picture {
Ok(Self {
pic_type,
data,
mime_type,
data,
})
}
}

View file

@ -16,6 +16,7 @@ use std::time::Duration;
impl_tag!(Mp4Tag, Mp4InnerTag, TagType::Mp4);
impl Mp4Tag {
#[allow(missing_docs)]
#[allow(clippy::missing_errors_doc)]
pub fn read_from_path<P>(path: P) -> Result<Self>
where

View file

@ -27,6 +27,7 @@ impl Default for RiffInnerTag {
}
impl RiffTag {
#[allow(missing_docs)]
#[allow(clippy::missing_errors_doc)]
pub fn read_from_path<P>(path: P) -> Result<Self>
where

View file

@ -4,7 +4,7 @@ use crate::components::logic;
use crate::tag::VorbisFormat;
use crate::{
impl_tag, Album, AnyTag, AudioTag, AudioTagEdit, AudioTagWrite, Error, MimeType, Picture,
Result, TagType, ToAny, ToAnyTag, PictureType
PictureType, Result, TagType, ToAny, ToAnyTag,
};
use std::collections::HashMap;
@ -184,6 +184,7 @@ impl_tag!(
);
impl VorbisTag {
#[allow(missing_docs)]
#[allow(clippy::missing_errors_doc)]
pub fn read_from_path<P>(path: P, format: VorbisFormat) -> Result<Self>
where
@ -350,7 +351,7 @@ impl AudioTagEdit for VorbisTag {
Some(pictures) => {
for pic in pictures {
if pic.pic_type == PictureType::CoverFront {
return Some(pic.clone())
return Some(pic.clone());
}
}
@ -375,7 +376,7 @@ impl AudioTagEdit for VorbisTag {
let encoded = base64::encode(encoded);
if let Ok(Some(pic))= picture_from_data(&*encoded) {
if let Ok(Some(pic)) = picture_from_data(&*encoded) {
if let Some(mut pictures) = self.inner.pictures.clone() {
pictures.retain(|p| p.pic_type != PictureType::CoverFront);
pictures.push(pic);

View file

@ -5,44 +5,60 @@ pub enum Error {
#[error("Failed to guess the metadata format based on the file extension.")]
UnknownFileExtension,
/// Unable to guess the format
#[error("No format could be determined from the provided file.")]
UnknownFormat,
/// Provided an empty file
#[error("File contains no data")]
EmptyFile,
/// Provided a file with invalid/malformed data
#[error("File has invalid data")]
InvalidData,
/// Unsupported file extension
#[error("Unsupported format: {0}")]
UnsupportedFormat(String),
/// Picture has an unsupported mime type
#[error("Unsupported mime type: {0}")]
UnsupportedMimeType(String),
/// Any error from [`ape`]
#[error(transparent)]
ApeTag(#[from] ape::Error),
/// Any error from [`metaflac`]
#[error(transparent)]
FlacTag(#[from] metaflac::Error),
/// Any error from [`id3`]
#[error(transparent)]
Id3Tag(#[from] id3::Error),
/// Any error from [`mp3_duration`]
#[cfg(feature = "duration")]
#[error(transparent)]
Mp3Duration(#[from] mp3_duration::MP3DurationError),
/// Any error from [`mp4ameta`]
#[error(transparent)]
Mp4Tag(#[from] mp4ameta::Error),
/// Any error from [`opus_headers`]
#[error(transparent)]
OpusTag(#[from] opus_headers::ParseError),
/// Any error from [`lewton`]
#[error(transparent)]
Lewton(#[from] lewton::VorbisError),
/// Any error from [`ogg`]
#[error(transparent)]
Ogg(#[from] ogg::OggReadError),
/// Errors that arise while reading/writing to wav files
#[error("{0}")]
Wav(String),
/// Failed to convert data to a picture
#[error("")]
NotAPicture,
/// If a string isn't Utf8
#[error(transparent)]
Utf8(#[from] std::str::Utf8Error),
/// Unable to convert bytes to a String
#[error(transparent)]
FromUtf8(#[from] std::string::FromUtf8Error),
/// Represents all cases of `std::io::Error`.
@ -51,5 +67,5 @@ pub enum Error {
IO(#[from] std::io::Error),
}
/// Type alias for the result of tag operations.
/// Type for the result of tag operations.
pub type Result<T> = std::result::Result<T, Error>;

View file

@ -68,6 +68,7 @@
//! unnecessary copies.
#![warn(clippy::pedantic)]
#![warn(missing_docs)]
#![allow(
clippy::too_many_lines,
clippy::cast_precision_loss,

View file

@ -21,6 +21,7 @@ macro_rules! impl_tag {
}
impl $tag {
/// Creates a new default tag
pub fn new() -> Self {
Self::default()
}

View file

@ -4,28 +4,40 @@ use crate::{Album, AnyTag, Picture, Result, TagType};
use std::fs::{File, OpenOptions};
/// Combination of [`AudioTagEdit`], [`AudioTagWrite`], and [`ToAnyTag`]
pub trait AudioTag: AudioTagEdit + AudioTagWrite + ToAnyTag {}
/// Implementors of this trait are able to read and write audio metadata.
///
/// Constructor methods e.g. `from_file` should be implemented separately.
pub trait AudioTagEdit {
/// Returns the track title
fn title(&self) -> Option<&str>;
/// Sets the track title
fn set_title(&mut self, title: &str);
/// Removes the track title
fn remove_title(&mut self);
/// Returns the artist(s) as a string
fn artist_str(&self) -> Option<&str>;
/// Sets the artist string
fn set_artist(&mut self, artist: &str);
/// Splits the artist string into a `Vec`
fn artists_vec(&self) -> Option<Vec<&str>> {
self.artist_str().map(|a| a.split('/').collect())
}
/// Removes the artist string
fn remove_artist(&mut self);
/// Returns the track year
fn year(&self) -> Option<i32>;
/// Sets the track year
fn set_year(&mut self, year: i32);
/// Removes the track year
fn remove_year(&mut self);
/// Returns the track's [`Album`]
fn album(&self) -> Album<'_> {
Album {
title: self.album_title(),
@ -34,60 +46,85 @@ pub trait AudioTagEdit {
}
}
/// Returns the album title
fn album_title(&self) -> Option<&str>;
/// Sets the album title
fn set_album_title(&mut self, v: &str);
/// Removes the album title
fn remove_album_title(&mut self);
/// Returns the album artist string
fn album_artist_str(&self) -> Option<&str>;
/// Splits the artist string into a `Vec`
fn album_artists_vec(&self) -> Option<Vec<&str>> {
self.album_artist_str().map(|a| a.split('/').collect())
}
/// Sets the album artist string
fn set_album_artist(&mut self, artist: &str);
/// Removes the album artist string
fn remove_album_artists(&mut self);
/// Returns the album cover
fn album_cover(&self) -> Option<Picture>;
/// Sets the album cover
fn set_album_cover(&mut self, cover: Picture);
/// Removes the album cover
fn remove_album_cover(&mut self);
/// Returns the track number and total tracks
fn track(&self) -> (Option<u32>, Option<u32>) {
(self.track_number(), self.total_tracks())
}
/// Sets the track number
fn set_track(&mut self, track: u32) {
self.set_track_number(track);
}
/// Removes the track number and total tracks
fn remove_track(&mut self) {
self.remove_track_number();
self.remove_total_tracks();
}
/// Returns the track number
fn track_number(&self) -> Option<u32>;
/// Sets the track number
fn set_track_number(&mut self, track_number: u32);
/// Removes the track number
fn remove_track_number(&mut self);
/// Returns the total tracks
fn total_tracks(&self) -> Option<u32>;
/// Sets the total tracks
fn set_total_tracks(&mut self, total_track: u32);
/// Removes the total tracks
fn remove_total_tracks(&mut self);
/// Returns the disc number and total discs
fn disc(&self) -> (Option<u32>, Option<u32>) {
(self.disc_number(), self.total_discs())
}
fn set_disc(&mut self, disc: u32) {
self.set_disc_number(disc);
}
/// Removes the disc number and total discs
fn remove_disc(&mut self) {
self.remove_disc_number();
self.remove_total_discs();
}
/// Returns the disc number
fn disc_number(&self) -> Option<u32>;
/// Sets the disc number
fn set_disc_number(&mut self, disc_number: u32);
/// Removes the disc number
fn remove_disc_number(&mut self);
/// Returns the total discs
fn total_discs(&self) -> Option<u32>;
/// Sets the total discs
fn set_total_discs(&mut self, total_discs: u32);
/// Removes the total discs
fn remove_total_discs(&mut self);
}
/// Functions for writing to a file
pub trait AudioTagWrite {
/// Write tag to a [`File`][std::fs::File]
///
@ -107,7 +144,9 @@ pub trait AudioTagWrite {
}
}
/// Conversions between tag types
pub trait ToAnyTag: ToAny {
/// Converts the tag to [`AnyTag`]
fn to_anytag(&self) -> AnyTag<'_>;
/// Convert the tag type, which can be lossy.
@ -129,8 +168,11 @@ pub trait ToAnyTag: ToAny {
}
}
/// Tag conversion to `Any`
pub trait ToAny {
/// Convert tag to `Any`
fn to_any(&self) -> &dyn std::any::Any;
/// Mutably convert tag to `Any`
#[allow(clippy::wrong_self_convention)]
fn to_any_mut(&mut self) -> &mut dyn std::any::Any;
}

View file

@ -3,8 +3,12 @@ use super::picture::Picture;
/// A struct for representing an album for convenience.
#[derive(Debug, Clone)]
pub struct Album<'a> {
/// The title of the album
pub title: Option<&'a str>,
/// A `Vec` of the album artists
pub artists: Option<Vec<&'a str>>,
/// The album's front cover
// TODO: also store the back cover
pub cover: Option<Picture>,
}

View file

@ -3,15 +3,25 @@ use crate::Album;
/// Used to convert between tags
#[derive(Default, Debug)]
pub struct AnyTag<'a> {
/// The track title
pub title: Option<&'a str>,
/// The track artists
pub artists: Option<Vec<&'a str>>,
/// The track [`Album`]
pub album: Album<'a>,
/// Collection of user comments
pub comments: Option<Vec<&'a str>>,
/// The track year
pub year: Option<i32>,
/// The track date
pub date: Option<&'a str>,
/// The track number
pub track_number: Option<u32>,
/// The total tracks
pub total_tracks: Option<u32>,
/// The disc number
pub disc_number: Option<u32>,
/// The total discs
pub total_discs: Option<u32>,
}

View file

@ -5,10 +5,15 @@ use std::convert::TryFrom;
/// Mime types for covers.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum MimeType {
/// PNG image
Png,
/// JPEG image
Jpeg,
/// TIFF image
Tiff,
/// BMP image
Bmp,
/// GIF image
Gif,
}
@ -47,8 +52,11 @@ impl From<MimeType> for String {
/// The picture type
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum PictureType {
/// Represents the front cover of an album
CoverFront,
/// Represents the back cover of an album
CoverBack,
/// Covers all other possible types
Other,
}
@ -65,17 +73,21 @@ impl From<&id3PicType> for PictureType {
/// Represents a picture, with its data and mime type.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Picture {
/// The picture type
pub pic_type: PictureType,
pub data: Vec<u8>,
/// The picture's mimetype
pub mime_type: MimeType,
/// The picture's actual data
pub data: Vec<u8>,
}
impl Picture {
/// Create a new `Picture`
pub fn new(pic_type: PictureType, data: Vec<u8>, mime_type: MimeType) -> Self {
Self {
pic_type,
data,
mime_type,
data,
}
}
}