Skip to content

Commit 23a6589

Browse files
authored
Merge pull request kstep#6 from jistr/fix-search
Fix the find/search functionality
2 parents cd0d4be + ee4018e commit 23a6589

File tree

3 files changed

+54
-41
lines changed

3 files changed

+54
-41
lines changed

src/client.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,10 +420,28 @@ impl<S: Read + Write> Client<S> {
420420
// TODO: list type [filtertype] [filterwhat] [...] [group] [grouptype] [...]
421421
// TODO: searchaddpl name type what [...], readcomments
422422

423-
/// Initiate query to songs database
424-
pub fn query<'a>(&'a mut self) -> Query<'a, S> {
425-
Query::new(self)
423+
/// Find songs matching Query conditions.
424+
pub fn find(&mut self, query: &Query) -> Result<Vec<Song>> {
425+
self.find_generic("find", query)
426426
}
427+
428+
/// Case-insensitively search for songs matching Query conditions.
429+
pub fn search(&mut self, query: &Query) -> Result<Vec<Song>> {
430+
self.find_generic("search", query)
431+
}
432+
433+
fn find_generic(&mut self, cmd: &str, query: &Query) -> Result<Vec<Song>> {
434+
let args = query.to_string();
435+
436+
self.run_command_fmt(format_args!("{} {}", cmd, args))
437+
.and_then(|_| {
438+
self.read_pairs()
439+
.split("file")
440+
.map(|v| v.and_then(FromMap::from_map))
441+
.collect()
442+
})
443+
}
444+
427445
// }}}
428446

429447
// Output methods {{{

src/search.rs

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -35,65 +35,38 @@ impl<'a> Filter<'a> {
3535
}
3636
}
3737

38-
pub struct Query<'a, S: 'a + Read + Write> {
39-
client: &'a mut Client<S>,
38+
pub struct Query<'a> {
4039
filters: Vec<Filter<'a>>,
4140
groups: Option<Vec<Cow<'a, str>>>,
4241
window: Option<(u32, u32)>,
4342
}
4443

45-
impl<'a, S: 'a + Read + Write> Query<'a, S> {
46-
pub fn new(client: &'a mut Client<S>) -> Query<'a, S> {
44+
impl<'a> Query<'a> {
45+
pub fn new() -> Query<'a> {
4746
Query {
48-
client: client,
4947
filters: Vec::new(),
5048
groups: None,
5149
window: None,
5250
}
5351
}
5452

55-
pub fn and<'b: 'a, V: 'b + Into<Cow<'b, str>>>(&'a mut self, term: Term<'b>, value: V) -> &'a mut Query<'a, S> {
53+
pub fn and<'b: 'a, V: 'b + Into<Cow<'b, str>>>(&'a mut self, term: Term<'b>, value: V) -> &'a mut Query<'a> {
5654
self.filters.push(Filter::new(term, value));
5755
self
5856
}
5957

60-
pub fn limit(&'a mut self, offset: u32, limit: u32) -> &'a mut Query<'a, S> {
58+
pub fn limit(&'a mut self, offset: u32, limit: u32) -> &'a mut Query<'a> {
6159
self.window = Some((offset, limit));
6260
self
6361
}
6462

65-
pub fn group<'b: 'a, G: 'b + Into<Cow<'b, str>>>(&'a mut self, group: G) -> &'a mut Query<'a, S> {
63+
pub fn group<'b: 'a, G: 'b + Into<Cow<'b, str>>>(&'a mut self, group: G) -> &'a mut Query<'a> {
6664
match self.groups {
6765
None => self.groups = Some(vec![group.into()]),
6866
Some(ref mut groups) => groups.push(group.into()),
6967
};
7068
self
7169
}
72-
73-
pub fn find(mut self, fuzzy: bool, add: bool) -> Result<Vec<Song>> {
74-
let cmd = if fuzzy { if add { "searchadd" } else { "search" } } else { if add { "findadd" } else { "find" } };
75-
let args = self.to_string();
76-
77-
self.client
78-
.run_command_fmt(format_args!("{} {}", cmd, args))
79-
.and_then(|_| {
80-
self.client
81-
.read_pairs()
82-
.split("file")
83-
.map(|v| v.and_then(FromMap::from_map))
84-
.collect()
85-
})
86-
}
87-
88-
pub fn find_add<N: ToPlaylistName>(mut self, playlist: N) -> Result<()> {
89-
let args = self.to_string();
90-
self.client
91-
.run_command_fmt(format_args!("searchaddpl {} {}", playlist.to_name(), args))
92-
.and_then(|_| self.client.expect_ok())
93-
}
94-
95-
// pub fn list(mut self, ty: &str) -> Result<Vec<???>> {
96-
// }
9770
}
9871

9972
impl<'a> fmt::Display for Term<'a> {
@@ -110,19 +83,19 @@ impl<'a> fmt::Display for Term<'a> {
11083

11184
impl<'a> fmt::Display for Filter<'a> {
11285
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113-
write!(f, "{} {}", self.typ, self.what)
86+
write!(f, " {} \"{}\"", self.typ, self.what)
11487
}
11588
}
11689

117-
impl<'a, S: 'a + Read + Write> fmt::Display for Query<'a, S> {
90+
impl<'a> fmt::Display for Query<'a> {
11891
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11992
for filter in &self.filters {
12093
try!(filter.fmt(f));
12194
}
12295

12396
if let Some(ref groups) = self.groups {
12497
for group in groups {
125-
try!(write!(f, "group {}", group));
98+
try!(write!(f, " group {}", group));
12699
}
127100
}
128101

tests/search.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,38 @@ extern crate mpd;
22

33
mod helpers;
44
use helpers::connect;
5+
use mpd::{Query, Term};
56

67
#[test]
78
fn search() {
89
let mut mpd = connect();
9-
let mut query = mpd.query();
10+
let mut query = Query::new();
1011
//query.and(mpd::Term::Any, "Soul");
11-
let songs = query.find(false, false);
12+
let songs = mpd.find(&query);
1213
println!("{:?}", songs);
1314
}
1415

16+
#[test]
17+
fn find_query_format() {
18+
let mut query = Query::new();
19+
let finished = query
20+
.and(Term::Tag("albumartist".into()), "Mac DeMarco")
21+
.and(Term::Tag("album".into()), "Salad Days")
22+
.limit(0, 2);
23+
assert_eq!(&finished.to_string(),
24+
" albumartist \"Mac DeMarco\" album \"Salad Days\" window 0:2");
25+
}
26+
27+
#[test]
28+
fn count_query_format() {
29+
let mut query = Query::new();
30+
let finished = query
31+
.and(Term::Tag("artist".into()), "Courtney Barnett")
32+
.group("album");
33+
assert_eq!(&finished.to_string(),
34+
" artist \"Courtney Barnett\" group album");
35+
}
36+
1537
/*
1638
#[test]
1739
fn count() {

0 commit comments

Comments
 (0)