mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-12-13 14:12:31 +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`]
|
||||
///
|
||||
/// The default language is empty.
|
||||
///
|
||||
/// NOTE: This will not be reflected in most tag formats.
|
||||
pub fn set_lang(&mut 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`]
|
||||
///
|
||||
/// The default description is empty.
|
||||
///
|
||||
/// NOTE: This will not be reflected in most tag formats.
|
||||
pub fn set_description(&mut self, description: String) {
|
||||
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`]
|
||||
pub fn key(&self) -> &ItemKey {
|
||||
&self.item_key
|
||||
|
|
|
@ -405,11 +405,52 @@ impl Tag {
|
|||
|
||||
/// Removes all items with the specified [`ItemKey`], and returns them
|
||||
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
|
||||
let mut split_idx = 0_usize;
|
||||
let mut split_idx = 0;
|
||||
|
||||
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);
|
||||
split_idx += 1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue