mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-12-12 21:52:33 +00:00
Add Tag::take_filter()
This commit is contained in:
parent
fcb5446922
commit
a523db78d1
2 changed files with 61 additions and 2 deletions
|
@ -828,18 +828,36 @@ impl TagItem {
|
||||||
|
|
||||||
/// Set a language for the [`TagItem`]
|
/// Set a language for the [`TagItem`]
|
||||||
///
|
///
|
||||||
|
/// The default language is empty.
|
||||||
|
///
|
||||||
/// NOTE: This will not be reflected in most tag formats.
|
/// NOTE: This will not be reflected in most tag formats.
|
||||||
pub fn set_lang(&mut self, lang: Lang) {
|
pub fn set_lang(&mut self, lang: Lang) {
|
||||||
self.lang = lang;
|
self.lang = lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the language of the [`TagItem`]
|
||||||
|
///
|
||||||
|
/// NOTE: This will not be reflected in most tag formats.
|
||||||
|
pub fn lang(&self) -> &Lang {
|
||||||
|
&self.lang
|
||||||
|
}
|
||||||
|
|
||||||
/// Set a description for the [`TagItem`]
|
/// Set a description for the [`TagItem`]
|
||||||
///
|
///
|
||||||
|
/// The default description is empty.
|
||||||
|
///
|
||||||
/// NOTE: This will not be reflected in most tag formats.
|
/// NOTE: This will not be reflected in most tag formats.
|
||||||
pub fn set_description(&mut self, description: String) {
|
pub fn set_description(&mut self, description: String) {
|
||||||
self.description = description;
|
self.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the description of the [`TagItem`]
|
||||||
|
///
|
||||||
|
/// NOTE: This will not be reflected in most tag formats.
|
||||||
|
pub fn description(&self) -> &str {
|
||||||
|
&self.description
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a reference to the [`ItemKey`]
|
/// Returns a reference to the [`ItemKey`]
|
||||||
pub fn key(&self) -> &ItemKey {
|
pub fn key(&self) -> &ItemKey {
|
||||||
&self.item_key
|
&self.item_key
|
||||||
|
|
|
@ -405,11 +405,52 @@ impl Tag {
|
||||||
|
|
||||||
/// Removes all items with the specified [`ItemKey`], and returns them
|
/// Removes all items with the specified [`ItemKey`], and returns them
|
||||||
pub fn take(&mut self, key: &ItemKey) -> impl Iterator<Item = TagItem> + '_ {
|
pub fn take(&mut self, key: &ItemKey) -> impl Iterator<Item = TagItem> + '_ {
|
||||||
|
self.take_filter(key, |_| true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes selected items with the specified [`ItemKey`], and returns them
|
||||||
|
///
|
||||||
|
/// Only takes items for which `filter()` returns `true`. All other items are retained.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use lofty::tag::{ItemKey, ItemValue, Tag, TagItem, TagType};
|
||||||
|
///
|
||||||
|
/// let mut tag = Tag::new(TagType::Id3v2);
|
||||||
|
/// tag.push(TagItem::new(
|
||||||
|
/// ItemKey::Comment,
|
||||||
|
/// ItemValue::Text("comment without description".to_owned()),
|
||||||
|
/// ));
|
||||||
|
/// let mut item = TagItem::new(
|
||||||
|
/// ItemKey::Comment,
|
||||||
|
/// ItemValue::Text("comment with description".to_owned()),
|
||||||
|
/// );
|
||||||
|
/// item.set_description("description".to_owned());
|
||||||
|
/// tag.push(item);
|
||||||
|
/// assert_eq!(tag.get_strings(&ItemKey::Comment).count(), 2);
|
||||||
|
///
|
||||||
|
/// // Extract all comment items with an empty description.
|
||||||
|
/// let comments = tag
|
||||||
|
/// .take_filter(&ItemKey::Comment, |item| item.description().is_empty())
|
||||||
|
/// .filter_map(|item| item.into_value().into_string())
|
||||||
|
/// .collect::<Vec<_>>();
|
||||||
|
/// assert_eq!(comments, vec!["comment without description".to_owned()]);
|
||||||
|
///
|
||||||
|
/// // The comments that didn't match the filter are still present.
|
||||||
|
/// assert_eq!(tag.get_strings(&ItemKey::Comment).count(), 1);
|
||||||
|
/// ```
|
||||||
|
pub fn take_filter(
|
||||||
|
&mut self,
|
||||||
|
key: &ItemKey,
|
||||||
|
mut filter: impl FnMut(&TagItem) -> bool,
|
||||||
|
) -> impl Iterator<Item = TagItem> + '_ {
|
||||||
// TODO: drain_filter
|
// TODO: drain_filter
|
||||||
let mut split_idx = 0_usize;
|
let mut split_idx = 0;
|
||||||
|
|
||||||
for read_idx in 0..self.items.len() {
|
for read_idx in 0..self.items.len() {
|
||||||
if self.items[read_idx].key() == key {
|
let item = &self.items[read_idx];
|
||||||
|
if item.key() == key && filter(item) {
|
||||||
self.items.swap(split_idx, read_idx);
|
self.items.swap(split_idx, read_idx);
|
||||||
split_idx += 1;
|
split_idx += 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue