use std::process::{Command, Output, Stdio}; use std::str::from_utf8; use super::prelude::*; const FIRST_LOAD_PREFIX: &str = "[download] Destination:"; const RELOAD_SUFFIX: &str = " has already been downloaded"; const PREFIX: &str = "[download] "; fn convert_output(out: &Output) -> Result, String> { match from_utf8(out.stdout.as_slice()) { Ok(string) => { let lines = string.split("\n"); let mut files = Vec::new(); for line in lines { if !line.is_empty() { let mut line = line.to_string(); let line_len = line.len(); if line.starts_with(FIRST_LOAD_PREFIX) { let file_name = line.split_off(FIRST_LOAD_PREFIX.len()); files.push(file_name.trim().to_string()); } else if line.ends_with(RELOAD_SUFFIX) { line.split_off(line_len - RELOAD_SUFFIX.len()); let file_name = line.split_off(PREFIX.len()); files.push(file_name.trim().to_string()); } } } let mut mp3s = Vec::new(); for file in files { mp3s.push(str::replace(file.as_str(), ".webm", ".mp3").to_string()); } Ok(mp3s) } Err(_) => Err("error converting output".to_string()), } } pub fn youtube_dl(uri: &str) -> Result, String> { let args = ["-f", "bestaudio/best", "-o", "%(title)s", uri]; let out = match Command::new("youtube-dl") .args(&args) .stdin(Stdio::null()) .output() { Ok(out) => out, Err(why) => return Err(format!("youtube-dl error {:?}", why)), }; if !out.status.success() { let stdout = match String::from_utf8(out.stdout) { Ok(string) => string, Err(_) => String::new(), }; let stderr = match String::from_utf8(out.stderr) { Ok(string) => string, Err(_) => String::new(), }; return Err(format!( "Shell error\nstdout: {}\nstderr: {}", stdout, stderr )); } let files = check_result!(convert_output(&out)); for file in &files { println!("file: {}", file); } let mut songs = Vec::new(); for file in files { songs.push(Song { name: file }) } Ok(songs) }