set multiple values in table

This commit is contained in:
🪞👃🪞 2025-03-23 18:40:27 +02:00
parent 29435bb937
commit 95aa9f8b02

View file

@ -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<RwLock<EntryInfo>>,
}
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<Ordering> {
self.path.partial_cmp(&other.path)
}
}
#[derive(Ord, Eq, PartialEq, PartialOrd, Debug)]
@ -101,10 +119,10 @@ impl<T> Column<T> {
pub struct Columns<T>(pub Vec<Column<T>>);
fn paths_under (entries: &mut [Entry], index: usize) -> Option<Vec<&mut Entry>> {
let path = if let Some(Entry {
path, info: EntryInfo::Directory { .. }, ..
}) = entries.get(index) {
fn paths_under (entries: &mut [Entry], index: usize) -> Option<Vec<Arc<RwLock<EntryInfo>>>> {
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<Vec<&mut Entry>>
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<Entry> {
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<Entry> {
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<Entry> {
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<Entry> {
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: &Path, depth: usize) -> Perhaps<Self> {
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<Arc<str>> {
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<Arc<str>> {
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<Arc<str>> {
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<Arc<str>> {
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<Arc<str>> {
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<Arc<str>> {
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<str> ) {
match self.info {
EntryInfo::Music { ref mut artist, .. } => *artist = Some(value.as_ref().into()),
_ => {}
}
pub fn set_artist (&self, value: &impl AsRef<str> ) {
self.info.write().unwrap().set_artist(value)
}
pub fn set_album (&mut self, value: &impl AsRef<str> ) {
match self.info {
EntryInfo::Music { ref mut album, .. } => *album = Some(value.as_ref().into()),
_ => {}
}
pub fn set_album (&self, value: &impl AsRef<str> ) {
self.info.write().unwrap().set_album(value)
}
pub fn set_title (&mut self, value: &impl AsRef<str> ) {
match self.info {
EntryInfo::Music { ref mut title, .. } => *title = Some(value.as_ref().into()),
_ => {}
}
pub fn set_title (&self, value: &impl AsRef<str> ) {
self.info.write().unwrap().set_title(value)
}
pub fn set_track (&mut self, value: &impl AsRef<str> ) {
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::<u32>() {
*track = Some(value)
}
},
_ => {}
}
pub fn set_track (&self, value: &impl AsRef<str> ) {
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<str> ) {
match self {
EntryInfo::Music { artist, .. } => *artist = Some(value.as_ref().into()),
_ => {}
}
}
pub fn set_album (&mut self, value: &impl AsRef<str> ) {
match self {
EntryInfo::Music { album, .. } => *album = Some(value.as_ref().into()),
_ => {}
}
}
pub fn set_title (&mut self, value: &impl AsRef<str> ) {
match self {
EntryInfo::Music { title, .. } => *title = Some(value.as_ref().into()),
_ => {}
}
}
pub fn set_track (&mut self, value: &impl AsRef<str> ) {
match self {
EntryInfo::Directory { .. } => todo!("set track for whole directory"),
EntryInfo::Music { track, .. } => {
if let Ok(value) = value.as_ref().trim().parse::<u32>() {
*track = Some(value)
}
},
_ => {}
}
}
}