From 95aa9f8b022297b8e6d0242677ca2e391bd3756b Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sun, 23 Mar 2025 18:40:27 +0200 Subject: [PATCH] set multiple values in table --- src/model.rs | 152 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 56 deletions(-) diff --git a/src/model.rs b/src/model.rs index 77d72ab..457299d 100644 --- a/src/model.rs +++ b/src/model.rs @@ -1,6 +1,7 @@ use crate::*; use std::fs::File; use std::io::{BufReader, Read}; +use std::cmp::{Eq, PartialEq, Ord, PartialOrd, Ordering}; use lofty::{file::TaggedFileExt, probe::Probe, tag::Accessor}; use byte_unit::{Byte, Unit::MB}; @@ -15,11 +16,28 @@ pub struct Taggart { pub editing: Option<(usize, String)>, } -#[derive(Ord, Eq, PartialEq, PartialOrd, Debug)] +#[derive(Debug)] pub struct Entry { pub path: PathBuf, pub depth: usize, - pub info: EntryInfo, + pub info: Arc>, +} + +impl Eq for Entry {} +impl PartialEq for Entry { + fn eq (&self, other: &Self) -> bool { + self.path.eq(&other.path) + } +} +impl Ord for Entry { + fn cmp (&self, other: &Self) -> Ordering { + self.path.cmp(&other.path) + } +} +impl PartialOrd for Entry { + fn partial_cmp (&self, other: &Self) -> Option { + self.path.partial_cmp(&other.path) + } } #[derive(Ord, Eq, PartialEq, PartialOrd, Debug)] @@ -101,10 +119,10 @@ impl Column { pub struct Columns(pub Vec>); -fn paths_under (entries: &mut [Entry], index: usize) -> Option> { - let path = if let Some(Entry { - path, info: EntryInfo::Directory { .. }, .. - }) = entries.get(index) { +fn paths_under (entries: &mut [Entry], index: usize) -> Option>>> { + let path = if let Some(Entry { path, info, .. }) = entries.get(index) + && let EntryInfo::Directory { .. } = &*info.read().unwrap() + { Some(path.clone()) } else { None @@ -113,7 +131,7 @@ fn paths_under (entries: &mut [Entry], index: usize) -> Option> let mut others = vec![]; for other in entries.iter_mut() { if other.path.starts_with(&path) && !other.is_dir() { - others.push(other); + others.push(other.info.clone()); } } Some(others) @@ -135,7 +153,9 @@ impl Default for Columns { Column::new(&"ARTIST", 30, |entry: &Entry|entry.artist()) .setter(|entries: &mut [Entry], index: usize, value: &str|{ if let Some(entries) = paths_under(entries, index) { - todo!("set artist for whole directory {:#?}", entries); + for entry in entries.iter() { + entry.write().unwrap().set_artist(&value); + } } else if let Some(entry) = entries.get_mut(index) { entry.set_artist(&value) } @@ -144,7 +164,9 @@ impl Default for Columns { Column::new(&"RELEASE", 30, |entry: &Entry|entry.album()) .setter(|entries: &mut [Entry], index: usize, value: &str|{ if let Some(entries) = paths_under(entries, index) { - todo!("set album for whole directory {:#?}", entries); + for entry in entries.iter() { + entry.write().unwrap().set_album(&value); + } } else if let Some(entry) = entries.get_mut(index) { entry.set_album(&value) } @@ -153,7 +175,9 @@ impl Default for Columns { Column::new(&"TRACK", 5, |entry: &Entry|entry.track()) .setter(|entries: &mut [Entry], index: usize, value: &str|{ if let Some(entries) = paths_under(entries, index) { - todo!("set track for whole directory {:#?}", entries); + for entry in entries.iter() { + entry.write().unwrap().set_track(&value); + } } else if let Some(entry) = entries.get_mut(index) { entry.set_track(&value) } @@ -162,7 +186,9 @@ impl Default for Columns { Column::new(&"TITLE", 80, |entry: &Entry|entry.title()) .setter(|entries: &mut [Entry], index: usize, value: &str|{ if let Some(entries) = paths_under(entries, index) { - todo!("set title for whole directory {:#?}", entries); + for entry in entries.iter() { + entry.write().unwrap().set_title(&value); + } } else if let Some(entry) = entries.get_mut(index) { entry.set_title(&value) } @@ -187,96 +213,81 @@ impl Entry { Ok(Some(Self { depth, path: path.into(), - info: EntryInfo::Directory { + info: Arc::new(RwLock::new(EntryInfo::Directory { hash_file: None, catalog_file: None, artist_file: None, release_file: None, - }, + })), })) } fn new_file (_: &impl AsRef, path: &Path, depth: usize) -> Perhaps { Ok(Some(Self { depth, - info: EntryInfo::new(path)?, + info: Arc::new(RwLock::new(EntryInfo::new(path)?)), path: path.into(), })) } pub fn is_dir (&self) -> bool { - matches!(self.info, EntryInfo::Directory { .. }) + matches!(&*self.info.read().unwrap(), EntryInfo::Directory { .. }) } pub fn is_mus (&self) -> bool { - matches!(self.info, EntryInfo::Music { .. }) + matches!(&*self.info.read().unwrap(), EntryInfo::Music { .. }) } pub fn is_img (&self) -> bool { - matches!(self.info, EntryInfo::Image { .. }) + matches!(&*self.info.read().unwrap(), EntryInfo::Image { .. }) } pub fn hash (&self) -> Option> { - match self.info { - EntryInfo::Image { ref hash, .. } => Some(hash.clone()), - EntryInfo::Music { ref hash, .. } => Some(hash.clone()), + match &*self.info.read().unwrap() { + EntryInfo::Image { hash, .. } => Some(hash.clone()), + EntryInfo::Music { hash, .. } => Some(hash.clone()), + EntryInfo::Unknown { hash, .. } => Some(hash.clone()), _ => None } } pub fn size (&self) -> Option> { - match self.info { - EntryInfo::Image { ref size, .. } => Some(size.clone()), - EntryInfo::Music { ref size, .. } => Some(size.clone()), + match &*self.info.read().unwrap() { + EntryInfo::Image { size, .. } => Some(size.clone()), + EntryInfo::Music { size, .. } => Some(size.clone()), + EntryInfo::Unknown { size, .. } => Some(size.clone()), _ => None } } pub fn artist (&self) -> Option> { - match self.info { - EntryInfo::Music { ref artist, .. } => artist.clone(), + match &*self.info.read().unwrap() { + EntryInfo::Music { artist, .. } => artist.clone(), _ => None } } pub fn album (&self) -> Option> { - match self.info { - EntryInfo::Music { ref album, .. } => album.clone(), + match &*self.info.read().unwrap() { + EntryInfo::Music { album, .. } => album.clone(), _ => None } } pub fn title (&self) -> Option> { - match self.info { - EntryInfo::Music { ref title, .. } => title.clone(), + match &*self.info.read().unwrap() { + EntryInfo::Music { title, .. } => title.clone(), _ => None } } pub fn track (&self) -> Option> { - match self.info { - EntryInfo::Music { ref track, .. } => track.map(|t|format!("{t}").into()).clone(), + match &*self.info.read().unwrap() { + EntryInfo::Music { track, .. } => track.map(|t|format!("{t}").into()).clone(), _ => None } } - pub fn set_artist (&mut self, value: &impl AsRef ) { - match self.info { - EntryInfo::Music { ref mut artist, .. } => *artist = Some(value.as_ref().into()), - _ => {} - } + pub fn set_artist (&self, value: &impl AsRef ) { + self.info.write().unwrap().set_artist(value) } - pub fn set_album (&mut self, value: &impl AsRef ) { - match self.info { - EntryInfo::Music { ref mut album, .. } => *album = Some(value.as_ref().into()), - _ => {} - } + pub fn set_album (&self, value: &impl AsRef ) { + self.info.write().unwrap().set_album(value) } - pub fn set_title (&mut self, value: &impl AsRef ) { - match self.info { - EntryInfo::Music { ref mut title, .. } => *title = Some(value.as_ref().into()), - _ => {} - } + pub fn set_title (&self, value: &impl AsRef ) { + self.info.write().unwrap().set_title(value) } - pub fn set_track (&mut self, value: &impl AsRef ) { - match self.info { - EntryInfo::Directory { .. } => todo!("set track for whole directory"), - EntryInfo::Music { ref mut track, .. } => { - if let Ok(value) = value.as_ref().trim().parse::() { - *track = Some(value) - } - }, - _ => {} - } + pub fn set_track (&self, value: &impl AsRef ) { + self.info.write().unwrap().set_track(value) } } impl EntryInfo { @@ -352,4 +363,33 @@ impl EntryInfo { hash: hex::encode(xxh3_64(&bytes).to_be_bytes()).into(), }) } + pub fn set_artist (&mut self, value: &impl AsRef ) { + match self { + EntryInfo::Music { artist, .. } => *artist = Some(value.as_ref().into()), + _ => {} + } + } + pub fn set_album (&mut self, value: &impl AsRef ) { + match self { + EntryInfo::Music { album, .. } => *album = Some(value.as_ref().into()), + _ => {} + } + } + pub fn set_title (&mut self, value: &impl AsRef ) { + match self { + EntryInfo::Music { title, .. } => *title = Some(value.as_ref().into()), + _ => {} + } + } + pub fn set_track (&mut self, value: &impl AsRef ) { + match self { + EntryInfo::Directory { .. } => todo!("set track for whole directory"), + EntryInfo::Music { track, .. } => { + if let Ok(value) = value.as_ref().trim().parse::() { + *track = Some(value) + } + }, + _ => {} + } + } }