• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

johnallen3d / mpc-rs / #177

27 Dec 2023 03:38PM UTC coverage: 19.014% (-1.1%) from 20.149%
#177

push

web-flow
feat: add `search` command (#83)

Relates to #16

0 of 40 new or added lines in 3 files covered. (0.0%)

1 existing line in 1 file now uncovered.

135 of 710 relevant lines covered (19.01%)

1.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

9.86
/cli/src/main.rs
1
#![deny(clippy::pedantic)]
2
#![allow(clippy::missing_errors_doc)]
3
#![allow(clippy::missing_panics_doc)]
4
use std::io::BufRead;
5

6
use clap::Parser;
7

8
mod args;
9

10
use args::{Cli, Commands, OnOff};
11
use mpd_easy::Client;
12

13
fn main() {
×
14
    let args = Cli::parse();
×
15

16
    // safe to unwrap because we have default values
17
    let mut mpd = match Client::new(
×
18
        &args.bind_to_address.unwrap(),
×
19
        &args.port.unwrap(),
×
20
        args.format.to(),
×
21
    ) {
22
        Ok(client) => client,
×
23
        Err(e) => handle_error(e),
×
24
    };
25

26
    let result = match args.command {
×
27
        Some(Commands::Add { path }) => {
×
28
            mpd.add(&input_or_stdin(path, std::io::stdin().lock()))
×
29
        }
30
        Some(Commands::Crop) => mpd.crop(),
×
31
        Some(Commands::Del { position }) => mpd.del(position),
×
32
        Some(Commands::Current) => mpd.current(),
×
33
        Some(Commands::Play { position }) => mpd.play(position),
×
34
        Some(Commands::Next) => mpd.next(),
×
35
        Some(Commands::Prev) => mpd.prev(),
×
36
        Some(Commands::Pause) => mpd.pause(),
×
37
        Some(Commands::PauseIfPlaying) => mpd.pause_if_playing(),
×
38
        Some(Commands::Toggle) => mpd.toggle(),
×
39
        Some(Commands::Cdprev) => mpd.cdprev(),
×
40
        Some(Commands::Stop) => mpd.stop(),
×
41
        Some(Commands::Seek { position }) => mpd.seek(&position),
×
42
        Some(Commands::Seekthrough { position }) => mpd.seekthrough(&position),
×
43

44
        Some(Commands::Clear) => mpd.clear(),
×
45
        Some(Commands::Outputs) => mpd.outputs(),
×
46
        Some(Commands::Enable { args }) => mpd.enable(args),
×
47
        Some(Commands::Disable { args }) => mpd.disable(args),
×
48
        Some(Commands::Toggleoutput { args }) => mpd.toggle_output(args),
×
49
        Some(Commands::Queued) => mpd.queued(),
×
50
        Some(Commands::Shuffle) => mpd.shuffle(),
×
51
        Some(Commands::Lsplaylists) => mpd.lsplaylists(),
×
52
        Some(Commands::Load { name, range }) => mpd.load(&name, range),
×
53
        Some(Commands::Insert { uri }) => {
×
54
            mpd.insert(&input_or_stdin(uri, std::io::stdin().lock()))
×
55
        }
56
        Some(Commands::Prio {
57
            priority,
×
58
            position_or_range,
×
59
        }) => mpd.prio(&priority, &position_or_range),
×
60
        Some(Commands::Playlist { name }) => mpd.playlist(name),
×
61
        Some(Commands::Listall { file }) => mpd.listall(file.as_deref()),
×
62
        Some(Commands::Ls { directory }) => mpd.ls(directory.as_deref()),
×
63
        Some(Commands::Repeat { state }) => mpd.repeat(OnOff::to(&state)),
×
64
        Some(Commands::Random { state }) => mpd.random(OnOff::to(&state)),
×
65
        Some(Commands::Single { state }) => mpd.single(OnOff::to(&state)),
×
NEW
66
        Some(Commands::Search { tag, query }) => {
×
NEW
67
            mpd.search(tag.to_str(), &query)
×
68
        }
69
        Some(Commands::Consume { state }) => mpd.consume(OnOff::to(&state)),
×
70
        Some(Commands::Crossfade { seconds }) => mpd.crossfade(seconds),
×
71

72
        Some(Commands::Save { name }) => mpd.save(&name),
×
73
        Some(Commands::Rm { name }) => mpd.rm(&name),
×
74
        Some(Commands::Volume { volume }) => mpd.set_volume(&volume),
×
75
        Some(Commands::Stats) => mpd.stats(),
×
76
        Some(Commands::Version) => mpd.version(),
×
77

78
        Some(Commands::Status) | None => mpd.current_status(),
×
79
    };
80

81
    match result {
×
82
        Ok(Some(output)) => println!("{output}"),
×
83
        Ok(None) => (),
×
84
        Err(e) => handle_error(e),
×
85
    }
86
}
87

88
fn handle_error(error: impl std::fmt::Display) -> ! {
×
89
    let err_text = error.to_string();
×
90
    if !err_text.is_empty() {
×
91
        println!("{err_text}");
×
92
    }
93
    std::process::exit(1);
×
94
}
95

96
fn input_or_stdin<R: BufRead>(path: Option<String>, reader: R) -> String {
×
97
    if let Some(p) = path {
3✔
98
        return p;
1✔
99
    }
100

101
    let mut buffer = String::new();
1✔
102
    let mut reader = reader;
1✔
103

104
    reader
1✔
105
        .read_line(&mut buffer)
1✔
106
        .expect("error reading from input");
107

108
    buffer.trim().to_string()
1✔
109
}
110

111
#[cfg(test)]
112
mod tests {
113
    use super::*;
114
    use std::io::Cursor;
115

116
    #[test]
117
    fn test_input_or_stdin_with_path() {
118
        let path = Some("some_path".to_string());
119
        let cursor = Cursor::new("not_used");
120

121
        let result = input_or_stdin(path, cursor);
122
        assert_eq!(result, "some_path");
123
    }
124

125
    #[test]
126
    fn test_input_or_stdin_with_stdin() {
127
        let cursor = Cursor::new("from_stdin\n");
128

129
        let result = input_or_stdin(None, cursor);
130
        assert_eq!(result, "from_stdin");
131
    }
132
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc