mirror of
https://codeberg.org/unspeaker/perch.git
synced 2025-12-06 17:46:42 +01:00
set multiple values in table
This commit is contained in:
parent
29435bb937
commit
95aa9f8b02
1 changed files with 96 additions and 56 deletions
152
src/model.rs
152
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<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)
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue