moc_rs/moc/
impl.rs

1use crate::common::{MocControl, MocInfo, MocSource, MocState};
2use crate::moc::{Moc, MocInterface};
3use std::{collections::HashMap, path::Path, process::Command, time::Duration};
4
5impl MocInterface for Moc {
6    fn new(moc_path: String) -> Self {
7        Moc { moc_path }
8    }
9
10    fn info(&self) -> MocInfo {
11        let output = Command::new(self.moc_path.clone())
12            .arg("--info")
13            .output()
14            .expect("failed to execute process");
15
16        if !output.status.success() {
17            panic!("server is not running"); // FIXME: return error instead of panicking
18        }
19
20        let info = String::from_utf8_lossy(&output.stdout);
21        let info = info.trim();
22        let mut infohmp: HashMap<String, String> = HashMap::new();
23        for i in info.split('\n') {
24            let kv = i.split(": ");
25            infohmp.insert(
26                kv.clone().next().unwrap().into(),
27                kv.clone().nth(1).unwrap_or("").into(),
28            );
29        }
30
31        let mocstate = match infohmp["State"].as_str() {
32            "STOP" => MocState::Stopped,
33            "PAUSE" => MocState::Paused,
34            "PLAY" => MocState::Playing,
35            _ => panic!("UNIMPLEMENTED MOCSTATE! CRASH AND BURN!!!!!"), // FIXME: make it return a result instead of panic
36        };
37
38        let mut moc_info;
39        if mocstate == MocState::Stopped {
40            moc_info = MocInfo::default().with_state(MocState::Stopped);
41        } else {
42            let file = infohmp["File"].clone();
43            let mocsource;
44            if file.starts_with("http") {
45                mocsource = MocSource::Url(file);
46            } else {
47                mocsource = MocSource::File(file.into());
48            }
49
50            let title = infohmp["Title"].clone();
51            let artist = infohmp["Artist"].clone();
52            let song_title = infohmp["SongTitle"].clone();
53            let album = infohmp["Album"].clone();
54            let current_time = infohmp["CurrentSec"].clone();
55            let bitrate = infohmp["Bitrate"].clone();
56            let avg_bitrate = infohmp["AvgBitrate"].clone();
57            let rate = infohmp["Rate"].clone();
58
59            moc_info = MocInfo::default()
60                .with_state(mocstate)
61                .with_file(mocsource)
62                .with_full_title(title)
63                .with_artist(artist)
64                .with_title(song_title)
65                .with_album(album)
66                .with_current_time(Duration::from_secs(current_time.parse::<u64>().unwrap()))
67                .with_bitrate(bitrate)
68                .with_avg_bitrate(avg_bitrate)
69                .with_rate(rate);
70
71            if infohmp.contains_key("TotalSec") {
72                moc_info = moc_info.with_total_time(Duration::from_secs(
73                    infohmp["TotalSec"].parse::<u64>().unwrap(),
74                ));
75            } else {
76                moc_info = moc_info.with_total_time(Duration::from_secs(0));
77            }
78        }
79
80        moc_info
81    }
82
83    fn clear_playlist(&mut self) -> bool {
84        let status = Command::new(self.moc_path.clone())
85            .arg("--clear")
86            .status()
87            .expect("failed to run process");
88
89        status.success()
90    }
91    fn play_playlist(&mut self) -> bool {
92        let status = Command::new(self.moc_path.clone())
93            .arg("--play")
94            .status()
95            .expect("failed to run process");
96
97        status.success()
98    }
99    fn immediate_play(&mut self, source: MocSource) -> bool {
100        let status = Command::new(self.moc_path.clone())
101            .arg("--playit")
102            .arg(source.to_str().unwrap())
103            .status()
104            .expect("failed to run process");
105
106        status.success()
107    }
108    fn stop_server(&mut self) -> bool {
109        let status = Command::new(self.moc_path.clone())
110            .arg("--exit")
111            .status()
112            .expect("failed to run process");
113
114        status.success()
115    }
116    fn start_server(&mut self) -> bool {
117        let status = Command::new(self.moc_path.clone())
118            .arg("--server")
119            .status()
120            .expect("failed to run process");
121
122        status.success()
123    }
124    fn next_song(&mut self) -> bool {
125        let status = Command::new(self.moc_path.clone())
126            .arg("--next")
127            .status()
128            .expect("failed to run process");
129
130        status.success()
131    }
132    fn previous_song(&mut self) -> bool {
133        let status = Command::new(self.moc_path.clone())
134            .arg("--previous")
135            .status()
136            .expect("failed to run process");
137
138        status.success()
139    }
140    fn stop_playback(&mut self) -> bool {
141        let status = Command::new(self.moc_path.clone())
142            .arg("--stop")
143            .status()
144            .expect("failed to run process");
145
146        status.success()
147    }
148    fn pause_playback(&mut self) -> bool {
149        let status = Command::new(self.moc_path.clone())
150            .arg("--pause")
151            .status()
152            .expect("failed to run process");
153
154        status.success()
155    }
156    fn resume_playback(&mut self) -> bool {
157        let status = Command::new(self.moc_path.clone())
158            .arg("--unpause")
159            .status()
160            .expect("failed to run process");
161
162        status.success()
163    }
164    fn set_volume(&mut self, vol: usize) -> bool {
165        let status = Command::new(self.moc_path.clone())
166            .arg("--volume")
167            .arg(format!("{}", vol))
168            .status()
169            .expect("failed to run process");
170
171        status.success()
172    }
173    fn increase_volume_by(&mut self, step: usize) -> bool {
174        let status = Command::new(self.moc_path.clone())
175            .arg("--volume")
176            .arg(format!("+{}", step))
177            .status()
178            .expect("failed to run process");
179
180        status.success()
181    }
182    fn decrease_volume_by(&mut self, step: usize) -> bool {
183        let status = Command::new(self.moc_path.clone())
184            .arg("--volume")
185            .arg(format!("-{}", step))
186            .status()
187            .expect("failed to run process");
188
189        status.success()
190    }
191    fn append_music(&mut self, path: &Path) -> bool {
192        let status = Command::new(self.moc_path.clone())
193            .arg("--append")
194            .arg(path.to_str().unwrap())
195            .status()
196            .expect("failed to run process");
197
198        status.success()
199    }
200    fn seek(&mut self, step: isize) -> bool {
201        let mut sign = String::from("");
202        if step.signum() == 1 {
203            sign.push('+')
204        }
205
206        let status = Command::new(self.moc_path.clone())
207            .arg("--seek")
208            .arg(format!("{}{}", sign, step))
209            .status()
210            .expect("failed to run process");
211
212        status.success()
213    }
214    fn jump_to(&mut self, time: Duration) -> bool {
215        let status = Command::new(self.moc_path.clone())
216            .arg("--jump")
217            .arg(format!("{}s", time.as_secs()))
218            .status()
219            .expect("failed to run process");
220
221        status.success()
222    }
223    fn enable_control(&mut self, control: MocControl) -> bool {
224        let string = match control {
225            MocControl::Autonext => "autonext",
226            MocControl::Repeat => "repeat",
227            MocControl::Shuffle => "shuffle",
228        };
229        let status = Command::new(self.moc_path.clone())
230            .arg("--on")
231            .arg(string)
232            .status()
233            .expect("failed to run process");
234
235        status.success()
236    }
237    fn disable_control(&mut self, control: MocControl) -> bool {
238        let string = match control {
239            MocControl::Autonext => "autonext",
240            MocControl::Repeat => "repeat",
241            MocControl::Shuffle => "shuffle",
242        };
243        let status = Command::new(self.moc_path.clone())
244            .arg("--off")
245            .arg(string)
246            .status()
247            .expect("failed to run process");
248
249        status.success()
250    }
251}