Use traits from the standard library instead of own methods

This commit is contained in:
Love 2023-03-06 07:47:52 +01:00
parent 09d0938476
commit 71ec8d5aad
2 changed files with 27 additions and 28 deletions

View File

@ -1,5 +1,5 @@
use std::{ use std::{
fmt, error, fmt,
fs::File, fs::File,
io::{self, Read, Write}, io::{self, Read, Write},
}; };
@ -30,8 +30,24 @@ impl DualWriter {
Ok(()) Ok(())
} }
}
pub fn get_string(self) -> Result<String, String> { impl TryFrom<Option<&str>> for DualWriter {
type Error = io::Error;
fn try_from(file_name: Option<&str>) -> Result<Self, Self::Error> {
Ok(if let Some(file_name) = file_name {
Self::File(File::create(&file_name)?)
} else {
Self::Buffer(Vec::<u8>::new())
})
}
}
impl TryInto<String> for DualWriter {
type Error = String;
fn try_into(self) -> Result<String, Self::Error> {
Ok(match self { Ok(match self {
Self::Buffer(buffer) => { Self::Buffer(buffer) => {
String::from_utf8(buffer).or(Err("Failed to decode buffer".to_owned()))? String::from_utf8(buffer).or(Err("Failed to decode buffer".to_owned()))?
@ -47,32 +63,16 @@ impl DualWriter {
} }
}) })
} }
pub fn new(file_name: Option<&str>) -> Result<Self, io::Error> {
Ok(if let Some(file_name) = file_name {
Self::File(File::create(&file_name)?)
} else {
Self::Buffer(Vec::<u8>::new())
})
}
} }
pub async fn download_with_progress( pub async fn download_with_progress(
link: &str, link: &str,
file_name: Option<&str>, file_name: Option<&str>,
) -> Result<DualWriter, String> { ) -> Result<DualWriter, Box<dyn error::Error>> {
let mut dual_writer = DualWriter::new(file_name).or(Err("Failed to create file".to_owned()))?; let mut dual_writer: DualWriter = file_name.try_into()?;
let client = Client::builder() let client = Client::builder().gzip(true).deflate(true).build()?;
.gzip(true) let resp = client.get(link).send().await?;
.deflate(true)
.build()
.or(Err("Failed to create client".to_owned()))?;
let resp = client
.get(link)
.send()
.await
.or(Err("Failed to connect server".to_owned()))?;
let content_length = if let Some(got_content_length) = resp.content_length() { let content_length = if let Some(got_content_length) = resp.content_length() {
got_content_length got_content_length
} else { } else {
@ -90,9 +90,7 @@ pub async fn download_with_progress(
while let Some(item) = stream.next().await { while let Some(item) = stream.next().await {
let bytes = item.unwrap(); let bytes = item.unwrap();
downloaded = cmp::min(downloaded + (bytes.len() as u64), content_length); downloaded = cmp::min(downloaded + (bytes.len() as u64), content_length);
dual_writer dual_writer.write(bytes)?;
.write(bytes)
.or(Err("Failed to write to file".to_owned()))?;
progress_bar.set_position(downloaded); progress_bar.set_position(downloaded);
} }

View File

@ -1,6 +1,6 @@
use std::{fs, ops::Deref, path::PathBuf, rc::Rc}; use std::{fs, ops::Deref, path::PathBuf, rc::Rc};
use crate::{download_with_progress, downloader::DualWriter, MAX_TRIES}; use crate::{download_with_progress, MAX_TRIES};
pub struct Playlist { pub struct Playlist {
pub content: String, pub content: String,
@ -79,8 +79,9 @@ impl Playlist {
let downloaded = download_with_progress(&url, None) let downloaded = download_with_progress(&url, None)
.await .await
.and_then(DualWriter::get_string); .map(TryInto::try_into);
if let Ok(content) = downloaded {
if let Ok(Ok(content)) = downloaded {
break Ok(content); break Ok(content);
} else if counter > MAX_TRIES { } else if counter > MAX_TRIES {
break Err("Failed to download playlist".to_owned()); break Err("Failed to download playlist".to_owned());