reimplemented the result with errors

This commit is contained in:
Nils Pukropp committed 2021-11-14 14:51:02 +01:00
1 parent 116f5ae314
commit 247b5b942d
4 files changed
+38 -107

No files matched your search

+2 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "ytd-rs" name = "ytd-rs"
version = "0.1.5" version = "0.1.6"
authors = ["Nils Pukropp <nils.pukropp@outlook.de>"] authors = ["Nils Pukropp <nils.pukropp@outlook.de>"]
edition = "2018" edition = "2018"
license-file ="LICENSE" license-file ="LICENSE"
@@ -16,3 +16,4 @@ youtube-dlc = []
[dependencies] [dependencies]
regex = "1.5" regex = "1.5"
thiserror = "1.0"
+4 -8
View File
@@ -6,7 +6,7 @@
This is a simple wrapper for [youtube-dl](https://youtube-dl.org/) in rust. This is a simple wrapper for [youtube-dl](https://youtube-dl.org/) in rust.
```rust ```rust
use ytd_rs::{YoutubeDL, ResultType, Arg}; use ytd_rs::{YoutubeDL, Arg};
use std::path::PathBuf; use std::path::PathBuf;
use std::error::Error; use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
@@ -18,14 +18,10 @@ fn main() -> Result<(), Box<dyn Error>> {
let ytd = YoutubeDL::new(&path, args, link)?; let ytd = YoutubeDL::new(&path, args, link)?;
// start download // start download
let download = ytd.download(); let download = ytd.download()?;
// check what the result is and print out the path to the download or the error // print out the download path
match download.result_type() { println!("Your download: {}", download.output_dir().to_string_lossy())
ResultType::SUCCESS => println!("Your download: {}", download.output_dir().to_string_lossy()),
ResultType::IOERROR | ResultType::FAILURE =>
println!("Couldn't start download: {}", download.output()),
};
Ok(()) Ok(())
} }
``` ```
+11
View File
@@ -0,0 +1,11 @@
use thiserror::Error;
#[derive(Error, Debug)]
pub enum YoutubeDLError {
#[error("failed to execute youtube-dl")]
IOError(#[from] std::io::Error),
#[error("failed to convert path")]
UTF8Error(#[from] std::string::FromUtf8Error),
#[error("youtube-dl exited with: {0}")]
Failure(String),
}
+21 -98
View File
@@ -3,7 +3,7 @@
//! # Example //! # Example
//! //!
//! ```no_run //! ```no_run
//! use ytd_rs::{YoutubeDL, ResultType, Arg}; //! use ytd_rs::{YoutubeDL, Arg};
//! use std::path::PathBuf; //! use std::path::PathBuf;
//! use std::error::Error; //! use std::error::Error;
//! fn main() -> Result<(), Box<dyn Error>> { //! fn main() -> Result<(), Box<dyn Error>> {
@@ -15,20 +15,16 @@
//! let ytd = YoutubeDL::new(&path, args, link)?; //! let ytd = YoutubeDL::new(&path, args, link)?;
//! //!
//! // start download //! // start download
//! let download = ytd.download(); //! let download = ytd.download()?;
//! //!
//! // check what the result is and print out the path to the download or the error //! // check what the result is and print out the path to the download or the error
//! match download.result_type() { //! println!("Your download: {}", download.output_dir().to_string_lossy());
//! ResultType::SUCCESS => println!("Your download: {}", download.output_dir().to_string_lossy()),
//! ResultType::IOERROR | ResultType::FAILURE =>
//! println!("Couldn't start download: {}", download.output()),
//! };
//! Ok(()) //! Ok(())
//! } //! }
//! ``` //! ```
use error::YoutubeDLError;
use std::{ use std::{
error::Error,
fmt, fmt,
process::{Output, Stdio}, process::{Output, Stdio},
}; };
@@ -39,6 +35,7 @@ use std::{
}; };
use std::{path::Path, process::Command}; use std::{path::Path, process::Command};
pub mod error;
type Result<T> = std::result::Result<T, YoutubeDLError>; type Result<T> = std::result::Result<T, YoutubeDLError>;
const YOUTUBE_DL_COMMAND: &str = if cfg!(feature = "youtube-dlc") { const YOUTUBE_DL_COMMAND: &str = if cfg!(feature = "youtube-dlc") {
@@ -98,31 +95,6 @@ impl Display for Arg {
} }
} }
#[derive(Debug)]
pub struct YoutubeDLError {
message: String,
}
impl YoutubeDLError {
pub fn new(message: &str) -> YoutubeDLError {
YoutubeDLError {
message: message.to_string(),
}
}
}
impl fmt::Display for YoutubeDLError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.message)
}
}
impl Error for YoutubeDLError {
fn description(&self) -> &str {
self.message.as_ref()
}
}
/// Structure that represents a youtube-dl task. /// Structure that represents a youtube-dl task.
/// ///
/// Every task needs a download location, a list of ['Arg'] that can be empty /// Every task needs a download location, a list of ['Arg'] that can be empty
@@ -144,7 +116,6 @@ pub struct YoutubeDL {
pub struct YoutubeDLResult { pub struct YoutubeDLResult {
path: PathBuf, path: PathBuf,
output: String, output: String,
kind: ResultType,
} }
impl YoutubeDLResult { impl YoutubeDLResult {
@@ -153,15 +124,9 @@ impl YoutubeDLResult {
YoutubeDLResult { YoutubeDLResult {
path: path.clone(), path: path.clone(),
output: String::new(), output: String::new(),
kind: ResultType::FAILURE,
} }
} }
/// get the exit status of the process
pub fn result_type(&self) -> &ResultType {
&self.kind
}
/// get the output of the youtube-dl process /// get the output of the youtube-dl process
pub fn output(&self) -> &str { pub fn output(&self) -> &str {
&self.output &self.output
@@ -173,14 +138,6 @@ impl YoutubeDLResult {
} }
} }
/// Represents the different exit types of the [`YoutubeDL`] process
#[derive(Debug, Clone)]
pub enum ResultType {
SUCCESS,
FAILURE,
IOERROR,
}
impl YoutubeDL { impl YoutubeDL {
/// Creates a new YoutubeDL job to be executed. /// Creates a new YoutubeDL job to be executed.
/// It takes a path where youtube-dl should be executed, a vec! of [`Arg`] that can be empty /// It takes a path where youtube-dl should be executed, a vec! of [`Arg`] that can be empty
@@ -198,31 +155,20 @@ impl YoutubeDL {
// check if it already exists // check if it already exists
if !path.exists() { if !path.exists() {
// if not create // if not create
if let Err(why) = create_dir_all(&path) { create_dir_all(&path)?;
return Err(YoutubeDLError::new(
format!(
"Error while creating directories {}: {:?}",
dl_path.to_string_lossy(),
why
)
.as_ref(),
));
}
} }
// return error if no directory // return error if no directory
if !path.is_dir() { if !path.is_dir() {
return Err(YoutubeDLError::new("Error: path is not a directory")); return Err(YoutubeDLError::IOError(std::io::Error::new(
std::io::ErrorKind::Other,
"path is not a directory",
)));
} }
// absolute path // absolute path
match canonicalize(dl_path) { let path = canonicalize(dl_path)?;
// return new youtube-dl job Ok(YoutubeDL { path, links, args })
Ok(path) => Ok(YoutubeDL { path, links, args }),
Err(why) => Err(YoutubeDLError::new(
format!("Error creating YouTubeDL: {:?}", why).as_ref(),
)),
}
} }
pub fn new(dl_path: &PathBuf, args: Vec<Arg>, link: &str) -> Result<YoutubeDL> { pub fn new(dl_path: &PathBuf, args: Vec<Arg>, link: &str) -> Result<YoutubeDL> {
@@ -230,27 +176,16 @@ impl YoutubeDL {
} }
/// Starts the download and returns when finished the result as [`YoutubeDLResult`]. /// Starts the download and returns when finished the result as [`YoutubeDLResult`].
pub fn download(&self) -> YoutubeDLResult { pub fn download(&self) -> Result<YoutubeDLResult> {
let pr_result = self.spawn_youtube_dl(); let output = self.spawn_youtube_dl()?;
let mut result = YoutubeDLResult::new(&self.path); let mut result = YoutubeDLResult::new(&self.path);
let output = match pr_result { if !output.status.success() {
Err(why) => { return Err(YoutubeDLError::Failure(String::from_utf8(output.stderr)?));
result.output = why.to_string();
result.kind = ResultType::IOERROR;
return result;
} }
Ok(output) => output, result.output = String::from_utf8(output.stdout)?;
};
if output.status.success() { Ok(result)
result.kind = ResultType::SUCCESS;
result.output = String::from_utf8_lossy(&output.stdout).to_string();
} else {
result.output = String::from_utf8_lossy(&output.stderr).to_string();
}
result
} }
fn spawn_youtube_dl(&self) -> Result<Output> { fn spawn_youtube_dl(&self) -> Result<Output> {
@@ -271,20 +206,8 @@ impl YoutubeDL {
cmd.arg(&link); cmd.arg(&link);
} }
let pr = match cmd.spawn() { let pr = cmd.spawn()?;
Err(why) => { Ok(pr.wait_with_output()?)
return Err(YoutubeDLError::new(
format!("Error, YoutubeDL exited with {:?}", why).as_ref(),
));
}
Ok(process) => process,
};
match pr.wait_with_output() {
Ok(output) => Ok(output),
Err(why) => Err(YoutubeDLError::new(
format!("Error, YoutubeDL exited with {:?}", why).as_ref(),
)),
}
} }
} }
@@ -306,7 +229,7 @@ mod tests {
)?; )?;
let regex = Regex::new(r"\d{4}\.\d{2}\.\d{2}")?; let regex = Regex::new(r"\d{4}\.\d{2}\.\d{2}")?;
let output = ytd.download(); let output = ytd.download()?;
// check output // check output
// fails if youtube-dl is not installed // fails if youtube-dl is not installed