wip: create/update/remove modified_tag

This commit is contained in:
🪞👃🪞 2025-04-05 14:54:38 +03:00
parent af8f08c765
commit 4badc2fd7b
3 changed files with 64 additions and 92 deletions

View file

@ -2,6 +2,8 @@ run:
cargo run -- -j16 ~/Studio/Camp cargo run -- -j16 ~/Studio/Camp
run2: run2:
cargo run -- -j16 ~/Music cargo run -- -j16 ~/Music
run3:
cargo run -- -j16 ~/Studio/Releases
build-release: build-release:
time cargo build -j4 --release time cargo build -j4 --release

View file

@ -7,7 +7,7 @@ use lofty::{
probe::Probe, probe::Probe,
file::TaggedFileExt, file::TaggedFileExt,
config::{ParseOptions, ParsingMode}, config::{ParseOptions, ParsingMode},
tag::{Accessor, Tag, TagItem, ItemKey, ItemValue} tag::{Accessor, Tag, TagItem, ItemKey, ItemValue, TagType}
}; };
pub enum Metadata { pub enum Metadata {
@ -22,7 +22,7 @@ pub enum Metadata {
hash: Arc<str>, hash: Arc<str>,
size: Arc<str>, size: Arc<str>,
original_tag: Option<Arc<Tag>>, original_tag: Option<Arc<Tag>>,
modified_tag: Option<Arc<Tag>>, modified_tag: Option<Arc<RwLock<Tag>>>,
}, },
Image { Image {
invalid: bool, invalid: bool,
@ -57,7 +57,7 @@ impl Metadata {
size: format!("{:#>8.2}", size).into(), size: format!("{:#>8.2}", size).into(),
invalid: false, invalid: false,
original_tag: tag.map(|t|t.clone().into()), original_tag: tag.map(|t|t.clone().into()),
modified_tag: tag.map(|t|t.clone().into()), modified_tag: tag.map(|t|Arc::new(t.clone().into())),
}) })
} else { } else {
Self::new_fallback(path) Self::new_fallback(path)
@ -124,132 +124,102 @@ impl Metadata {
} }
macro_rules! music_tag_field { macro_rules! music_tag_field {
(string: $get:ident $set:ident $key:expr) => { (string: $get:ident $set:ident $del:ident $key:expr) => {
impl Metadata { impl Metadata {
pub fn $get (&self) -> Option<Arc<str>> { pub fn $get (&self) -> Option<Arc<str>> {
if let Metadata::Music { original_tag, modified_tag, .. } = self { if let Metadata::Music { original_tag, modified_tag, .. } = self {
return modified_tag return modified_tag.as_ref()
.as_ref() .map(|tag|tag.read().unwrap().$get().map(|t|t.into()))
.map(|tag|tag.$get().map(|t|t.into()))
.flatten() .flatten()
.or_else(||original_tag .or_else(||original_tag.as_ref()
.as_ref()
.map(|tag|tag.$get().map(|t|t.into())) .map(|tag|tag.$get().map(|t|t.into()))
.flatten()) .flatten())
} }
None None
} }
pub fn $set (&mut self, value: &impl AsRef<str>) -> Option<TagItem> { pub fn $set (&mut self, value: &impl AsRef<str>) -> Option<TagItem> {
if let Metadata::Music { original_tag, modified_tag, .. } = self { let value = value.as_ref().trim();
let value = value.as_ref().trim(); if let &mut Metadata::Music { ref original_tag, ref mut modified_tag, .. } = self {
match (value.len(), original_tag, modified_tag) { match (value.len(), &modified_tag) {
(0, Some(old_tag), Some(new_tag)) => { (0, Some(new_tag)) => {
if new_tag.read().unwrap().item_count() <= 1 {
// removing last entry removes modified_tag
*modified_tag = None;
} else {
// remove entry from modified_tag
new_tag.write().unwrap().$del();
}
}, },
(_, Some(old_tag), Some(new_tag)) => { (_, Some(new_tag)) => {
// add entry to modified_tag
new_tag.write().unwrap().$set(value.into())
}, },
(0, Some(old_tag), None) => { (0, None) => {
// leave modified_tag empty
}, },
(_, Some(old_tag), None) => { (_, None) => {
}, // first entry creates modified_tag
(0, None, Some(new_tag)) => { let mut new_tag = Tag::new(TagType::Id3v2); // FIXME other types
}, new_tag.$set(value.into());
(_, None, Some(new_tag)) => { *modified_tag = Some(Arc::new(RwLock::new(new_tag)));
},
(0, None, None) => {
unimplemented!("specifying new tag type")
},
(_, None, None) => {
unimplemented!("specifying new tag type")
}, },
} }
//let value = value.as_ref().trim();
//if value.len() > 0 {
//if old_tag.$get().is_none() {
//old_tag.$set(value)
//}
//if let Some(old_value) = old_tag.$get() {
//}
//} else {
//}
} }
//if let Metadata::Music { tag: Some(tag), .. } = self
//&& Some(value.as_ref()) != tag.$get().as_deref()
//{
//*$field = Some(value.as_ref().into());
//return Some(TagItem::new($key, ItemValue::Text(value.as_ref().into())))
//}
None None
} }
} }
}; };
(number: $get:ident $set:ident $key:expr) => { (number: $get:ident $set:ident $del:ident $key:expr) => {
impl Metadata { impl Metadata {
pub fn $get (&self) -> Option<Arc<str>> { pub fn $get (&self) -> Option<Arc<str>> {
if let Metadata::Music { original_tag, modified_tag, .. } = self { if let Metadata::Music { original_tag, modified_tag, .. } = self {
return modified_tag return modified_tag.as_ref()
.as_ref() .map(|tag|tag.read().unwrap().$get().map(|t|format!("{t}").into()))
.map(|tag|tag.$get().map(|t|format!("{t}").into()))
.flatten() .flatten()
.or_else(||original_tag .or_else(||original_tag.as_ref()
.as_ref()
.map(|tag|tag.$get().map(|t|format!("{t}").into())) .map(|tag|tag.$get().map(|t|format!("{t}").into()))
.flatten()) .flatten())
} }
None None
} }
pub fn $set (&mut self, value: &impl AsRef<str>) -> Option<TagItem> { pub fn $set (&mut self, value: &impl AsRef<str>) -> Option<TagItem> {
if let Metadata::Music { original_tag, modified_tag, .. } = self { let value = value.as_ref().trim();
let value = value.as_ref().trim(); if let &mut Metadata::Music { ref original_tag, ref mut modified_tag, .. } = self
match (value.len(), original_tag, modified_tag) { && let Ok(numeric_value) = value.parse::<u32>()
(0, Some(old_tag), Some(new_tag)) => { {
match (value.len(), &modified_tag) {
(0, Some(new_tag)) => {
if new_tag.read().unwrap().item_count() <= 1 {
// removing last entry removes modified_tag
*modified_tag = None;
} else {
// remove entry from modified_tag
new_tag.write().unwrap().$del();
}
}, },
(_, Some(old_tag), Some(new_tag)) => { (_, Some(new_tag)) => {
// add entry to modified_tag
new_tag.write().unwrap().$set(numeric_value)
}, },
(0, Some(old_tag), None) => { (0, None) => {
// leave modified_tag empty
}, },
(_, Some(old_tag), None) => { (_, None) => {
}, // first entry creates modified_tag
(0, None, Some(new_tag)) => { let mut new_tag = Tag::new(TagType::Id3v2); // FIXME other types
}, new_tag.$set(numeric_value);
(_, None, Some(new_tag)) => { *modified_tag = Some(Arc::new(RwLock::new(new_tag)));
},
(0, None, None) => {
unimplemented!("specifying new tag type")
},
(_, None, None) => {
unimplemented!("specifying new tag type")
}, },
} }
} }
None None
//let value = value.as_ref().trim();
//if value.len() > 0 {
//if let Ok(value) = value.parse::<u32>() {
//if let Metadata::Music {
//tag: Some(old_tag), new_tag: Some(new_tag), ..
//} = self {
//if old_tag.$get().is_none() {
//}
//if let Some(old_value) = old_tag.$get() {
//}
//}
//}
//} else {
//}
//if let Metadata::Music { tag: Some(tag), .. } = self
//&& let Ok(value) = value.as_ref().trim().parse::<u32>()
//&& Some(value) != *$field
//{
//*$field = Some(value);
//return Some(TagItem::new($key, ItemValue::Text(format!("{value}"))))
//}
} }
} }
}; };
} }
music_tag_field!(string: artist set_artist ItemKey::TrackArtist); music_tag_field!(string: artist set_artist remove_artist ItemKey::TrackArtist);
music_tag_field!(number: year set_year ItemKey::Year); music_tag_field!(number: year set_year remove_year ItemKey::Year);
music_tag_field!(string: album set_album ItemKey::AlbumTitle); music_tag_field!(string: album set_album remove_album ItemKey::AlbumTitle);
music_tag_field!(number: track set_track ItemKey::TrackNumber); music_tag_field!(number: track set_track remove_track ItemKey::TrackNumber);
music_tag_field!(string: title set_title ItemKey::TrackTitle); music_tag_field!(string: title set_title remove_title ItemKey::TrackTitle);

View file

@ -87,11 +87,11 @@ impl Taggart {
Fill::x( Fill::x(
Bsp::a( Bsp::a(
Fill::x(Align::w(format!( Fill::x(Align::w(format!(
" {}/{} {}", " {:>03}/{:>03} {}",
self.cursor + 1, self.cursor + 1,
self.entries.len(), self.entries.len(),
(self.columns.0[self.column].getter)(&self.entries[self.cursor]) (self.columns.0[self.column].getter)(&self.entries[self.cursor])
.map(|value|format!("{}: {value}", self.columns.0[self.column].title,)) .map(|value|format!("{}: {}", self.columns.0[self.column].title, value.trim()))
.unwrap_or(String::default()) .unwrap_or(String::default())
))), ))),
Fill::x(Align::e(format!( Fill::x(Align::e(format!(