Basic Search trait for lists

devel
~erin 2023-03-22 22:17:34 -04:00
parent ef19940418
commit 09ccbe9cd4
Signed by: erin
GPG Key ID: 9A8E308CEFA37A47
3 changed files with 88 additions and 62 deletions

View File

@ -25,7 +25,7 @@ use paris::{error, info};
use serde::{Deserialize, Serialize};
mod structs;
use structs::{App, InputMode, StatefulList, Blocks, SongList};
use structs::{App, InputMode, StatefulList, Blocks, SongList, Search};
#[derive(Deserialize, Serialize)]
struct Config {
@ -171,10 +171,10 @@ fn run_app<B: Backend>(
loop {
terminal.draw(|f| ui(f, &mut app))?;
let timeout = tick_rate
.checked_sub(last_tick.elapsed())
.unwrap_or_else(|| Duration::from_millis(1));
if crossterm::event::poll(timeout)? {
if let Event::Key(key) = event::read()? {
match app.input_mode {
@ -186,19 +186,55 @@ fn run_app<B: Backend>(
KeyCode::Char('s') => app.mpd_client.stop().unwrap(),
KeyCode::Tab => app.switch_block(),
KeyCode::Char('l') => {
match app.songs.choose() {
Some(s) => {
match app.mpd_client.clear() {
Ok(..) => {},
Err(e) => error!("Could not clear queue: {}", e),
match app.selected_block {
Blocks::Songs => {
match app.songs.choose() {
Some(s) => {
match app.mpd_client.clear() {
Ok(..) => {},
Err(e) => error!("Could not clear queue: {}", e),
}
match app.mpd_client.push(s) {
Ok(..) => {},
Err(e) => error!("Cannot play song! {}", e),
}
app.mpd_client.play().unwrap();
},
None => {},
}
match app.mpd_client.push(s) {
Ok(..) => {},
Err(e) => error!("Cannot play song! {}", e),
}
app.mpd_client.play().unwrap();
},
None => {},
Blocks::Artists => {
// match app.artists.choose() {
// Some(s) => {
// match app.mpd_client.clear() {
// Ok(..) => {},
// Err(e) => error!("Could not clear queue: {}", e),
// }
// match app.mpd_client.push(s) {
// Ok(..) => {},
// Err(e) => error!("Cannot play song! {}", e),
// }
// app.mpd_client.play().unwrap();
// },
// None => {},
// }
},
Blocks::Albums => {
// match app.albums.choose() {
// Some(s) => {
// match app.mpd_client.clear() {
// Ok(..) => {},
// Err(e) => error!("Could not clear queue: {}", e),
// }
// match app.mpd_client.push(s) {
// Ok(..) => {},
// Err(e) => error!("Cannot play song! {}", e),
// }
// app.mpd_client.play().unwrap();
// },
// None => {},
// }
},
}
},
KeyCode::Char('h') => {
@ -233,65 +269,20 @@ fn run_app<B: Backend>(
Some(r) => r,
None => "",
};
app.last_songs = match app.mpd_client.search(&Query::new().and(Term::File, last_results), (0,50)) {
Ok(s) => {
let mut results: Vec<(String, usize, Option<Song>)> = vec![];
let mut x = 0;
for i in s {
let name = match i.title.clone() {
Some(n) => n,
None => "<unnamed>".to_string(),
};
results.push((name, x, Some(i.clone())));
x+=1;
}
results
},
Err(e) => vec![("<no results>".to_string(), 0, None)],
};
app.last_songs = app.songs.mpd_search(&mut app.mpd_client, last_results.to_string(), (0,50));
app.songs = SongList::with_items(app.last_songs.clone());
app.input_mode = InputMode::Normal;
}
KeyCode::Char(c) => {
app.input.push(c);
let results = app.input.clone();
app.last_songs = match app.mpd_client.search(&Query::new().and(Term::File, results), (0,50)) {
Ok(s) => {
let mut results: Vec<(String, usize, Option<Song>)> = vec![];
let mut x = 0;
for i in s {
let name = match i.title.clone() {
Some(n) => n,
None => "<unnamed>".to_string(),
};
results.push((name, x, Some(i.clone())));
x+=1;
}
results
},
Err(e) => vec![("<no results>".to_string(), 0, None)],
};
app.last_songs = app.songs.mpd_search(&mut app.mpd_client, results.to_string(), (0,50));
app.songs = SongList::with_items(app.last_songs.clone());
}
KeyCode::Backspace => {
app.input.pop();
let results = app.input.clone();
app.last_songs = match app.mpd_client.search(&Query::new().and(Term::File, results), (0,50)) {
Ok(s) => {
let mut results: Vec<(String, usize, Option<Song>)> = vec![];
let mut x = 0;
for i in s {
let name = match i.title.clone() {
Some(n) => n,
None => "<unnamed>".to_string(),
};
results.push((name, x, Some(i.clone())));
x+=1;
}
results
},
Err(e) => vec![("<no results>".to_string(), 0, None)],
};
app.last_songs = app.songs.mpd_search(&mut app.mpd_client, results.to_string(), (0,50));
app.songs = SongList::with_items(app.last_songs.clone());
}
_ => {}

0
src/search.rs Normal file
View File

View File

@ -4,7 +4,14 @@ use tui::widgets::ListState;
use paris::error;
use std::process::exit;
use mpd::song::Song;
use mpd::{song::Song, Query, Term};
pub trait Search {
type Item;
fn mpd_search(&self, client: &mut Client, query: String, range: (u32, u32)) -> Vec<Self::Item>;
fn fuzzy_search(&self, client: &Client, query: String, range: (u32, u32)) -> Vec<Self::Item>;
}
pub trait StatefulList {
type Item;
@ -23,6 +30,34 @@ pub struct SongList {
pub items: Vec<(String, usize, Option<Song>)>,
}
impl Search for SongList {
type Item = (String, usize, Option<Song>);
fn mpd_search(&self, client: &mut Client, query: String, range: (u32, u32)) -> Vec<Self::Item> {
match client.search(&Query::new().and(Term::File, query), range) {
Ok(s) => {
let mut results: Vec<(String, usize, Option<Song>)> = vec![];
let mut x = 0;
for i in s {
let name = match i.title.clone() {
Some(n) => n,
None => "<unnamed>".to_string(),
};
results.push((name, x, Some(i.clone())));
x += 1;
}
results
},
Err(e) => vec![("<no results>".to_string(), 0, None)],
}
}
fn fuzzy_search(&self, client: &Client, query: String, range: (u32, u32)) -> Vec<Self::Item> {
error!("Unimplemented!");
exit(1);
}
}
impl StatefulList for SongList {
type Item = (String, usize, Option<Song>);
type List = SongList;