OggTag cleanup

Signed-off-by: Serial <69764315+Serial-ATA@users.noreply.github.com>
This commit is contained in:
Serial 2021-07-07 22:46:02 -04:00
parent 09c248c6c9
commit f46cd1b301

View file

@ -39,31 +39,6 @@ impl Default for OggInnerTag {
}
impl OggInnerTag {
fn get_value(&self, key: &str) -> Option<&str> {
self.comments.get_key_value(key).and_then(|pair| {
if pair.1.is_empty() {
None
} else {
Some(pair.1.as_str())
}
})
}
fn set_value<V>(&mut self, key: &str, val: V)
where
V: Into<String>,
{
let mut comments = self.comments.clone();
let _ = comments.insert(key.to_string(), val.into());
self.comments = comments;
}
fn remove_key(&mut self, key: &str) {
let mut comments = self.comments.clone();
comments.retain(|k, _| k != key);
self.comments = comments;
}
fn read_from<R>(reader: &mut R, format: &OggFormat) -> Result<Self>
where
R: Read + Seek,
@ -97,6 +72,21 @@ impl OggInnerTag {
},
}
}
fn get_value(&self, key: &str) -> Option<&str> {
self.comments.get_key_value(key).map(|(_, v)| v.as_str())
}
fn set_value<V>(&mut self, key: &str, val: V)
where
V: Into<String>,
{
self.comments.insert(key.to_string(), val.into());
}
fn remove_key(&mut self, key: &str) {
self.comments.remove(key);
}
}
cfg_if::cfg_if! {
@ -119,17 +109,14 @@ impl TryFrom<OGGTags> for OggTag {
fn try_from(inp: OGGTags) -> Result<Self> {
let mut tag = Self::default();
let vendor = inp.0;
let pictures = inp.1;
let comments = inp.2;
tag.inner = OggInnerTag {
vendor: inp.0,
comments: comments.into_iter().collect(),
pictures: if pictures.is_empty() {
None
} else {
Some(Cow::from(pictures))
},
vendor,
comments,
pictures: (!pictures.is_empty()).then(|| Cow::from(pictures)),
};
Ok(tag)
@ -144,32 +131,28 @@ impl TryFrom<metaflac::Tag> for OggTag {
let mut tag = Self::default();
if let Some(comments) = inp.vorbis_comments() {
let comments = comments.clone();
let mut user_comments = comments.comments;
let mut user_comments = comments.comments.clone();
let mut pictures = Vec::new();
if let Some(data) = user_comments.remove("METADATA_BLOCK_PICTURE") {
for item in data {
if let Ok(pic) = Picture::from_apic_bytes(&item.as_bytes()) {
if let Some(pics) = user_comments.remove("METADATA_BLOCK_PICTURE") {
pics.iter().for_each(|item| {
if let Ok(pic) = Picture::from_apic_bytes(item.as_bytes()) {
pictures.push(pic)
}
}
})
}
let mut comment_collection = Vec::new();
let mut comment_collection: HashMap<String, String> = HashMap::new();
for (k, v) in user_comments.clone() {
for e in v {
comment_collection.push((k.clone(), e.clone()))
comment_collection.insert(k.clone(), e.clone());
}
}
let comment_collection: HashMap<String, String> =
comment_collection.into_iter().collect();
tag.inner = OggInnerTag {
vendor: comments.vendor_string,
vendor: comments.vendor_string.clone(),
comments: comment_collection,
pictures: Some(Cow::from(pictures)),
};
@ -234,25 +217,23 @@ impl AudioTagEdit for OggTag {
}
fn year(&self) -> Option<i32> {
if let Some(Ok(y)) = self
if let Some(Ok(y)) = self.inner.get_value("YEAR").map(str::parse::<i32>) {
return Some(y);
} else if let Some(Ok(y)) = self
.inner
.get_value("DATE")
.map(|s| s.chars().take(4).collect::<String>().parse::<i32>())
.map(|d| (&d[..4]).parse::<i32>())
{
Some(y)
} else if let Some(Ok(y)) = self.inner.get_value("YEAR").map(str::parse::<i32>) {
Some(y)
} else {
None
return Some(y);
}
None
}
fn set_year(&mut self, year: i32) {
self.inner.set_value("DATE", &year.to_string());
self.inner.set_value("YEAR", &year.to_string());
}
fn remove_year(&mut self) {
self.inner.remove_key("YEAR");
self.inner.remove_key("DATE");
}
fn album_title(&self) -> Option<&str> {
@ -278,40 +259,66 @@ impl AudioTagEdit for OggTag {
}
fn front_cover(&self) -> Option<Picture> {
get_cover(PictureType::CoverFront, &self.inner.pictures)
if let Some(p) = &self.inner.pictures {
return p
.iter()
.find(|c| c.pic_type == PictureType::CoverFront)
.cloned();
}
None
}
#[allow(clippy::collapsible_if)]
fn set_front_cover(&mut self, cover: Picture) {
if let Some(pic) = create_cover(&cover) {
self.remove_front_cover();
self.inner.pictures = Some(replace_pic(pic, &self.inner.pictures))
if PictureType::CoverFront == cover.pic_type {
if let Ok(pic) = Picture::from_apic_bytes(&cover.as_apic_bytes()) {
self.remove_back_cover();
if let Some(p) = self.inner.pictures.as_mut().map(std::borrow::Cow::to_mut) {
p.push(pic)
} else {
self.inner.pictures = Some(Cow::from(vec![pic]))
}
}
}
}
fn remove_front_cover(&mut self) {
if let Some(p) = self.inner.pictures.clone() {
let mut p = p.to_vec();
p.retain(|pic| Some(pic) != self.front_cover().as_ref());
self.inner.pictures = Some(Cow::from(p));
if let Some(p) = self.inner.pictures.as_mut().map(std::borrow::Cow::to_mut) {
p.retain(|pic| pic.pic_type != PictureType::CoverFront)
}
}
fn back_cover(&self) -> Option<Picture> {
get_cover(PictureType::CoverBack, &self.inner.pictures)
if let Some(p) = &self.inner.pictures {
return p
.iter()
.find(|c| c.pic_type == PictureType::CoverBack)
.cloned();
}
None
}
#[allow(clippy::collapsible_if)]
fn set_back_cover(&mut self, cover: Picture) {
if let Some(pic) = create_cover(&cover) {
self.remove_back_cover();
self.inner.pictures = Some(replace_pic(pic, &self.inner.pictures))
if PictureType::CoverBack == cover.pic_type {
if let Ok(pic) = Picture::from_apic_bytes(&cover.as_apic_bytes()) {
self.remove_back_cover();
if let Some(p) = self.inner.pictures.as_mut().map(std::borrow::Cow::to_mut) {
p.push(pic)
} else {
self.inner.pictures = Some(Cow::from(vec![pic]))
}
}
}
}
fn remove_back_cover(&mut self) {
if let Some(p) = self.inner.pictures.clone() {
let mut p = p.to_vec();
p.retain(|pic| Some(pic) != self.back_cover().as_ref());
self.inner.pictures = Some(Cow::from(p));
if let Some(p) = self.inner.pictures.as_mut().map(std::borrow::Cow::to_mut) {
p.retain(|pic| pic.pic_type != PictureType::CoverBack)
}
}
@ -378,47 +385,6 @@ impl AudioTagEdit for OggTag {
}
}
fn get_cover(p_type: PictureType, pictures: &Option<Cow<'static, [Picture]>>) -> Option<Picture> {
match pictures {
None => None,
Some(pictures) => {
for pic in pictures.iter() {
if pic.pic_type == p_type {
return Some(pic.clone());
}
}
None
},
}
}
fn create_cover(cover: &Picture) -> Option<Picture> {
if cover.pic_type == PictureType::CoverFront || cover.pic_type == PictureType::CoverBack {
if let Ok(pic) = Picture::from_apic_bytes(&cover.as_apic_bytes()) {
return Some(pic);
}
}
None
}
fn replace_pic(
pic: Picture,
pictures: &Option<Cow<'static, [Picture]>>,
) -> Cow<'static, [Picture]> {
if let Some(pictures) = pictures {
let mut pictures = pictures.to_vec();
pictures.retain(|p| p.pic_type != pic.pic_type);
pictures.push(pic);
Cow::from(pictures)
} else {
Cow::from(vec![pic])
}
}
impl AudioTagWrite for OggTag {
fn write_to(&self, file: &mut File) -> Result<()> {
let mut sig = [0; 4];