diff --git a/src/extend.rs b/src/extend.rs new file mode 100644 index 0000000..8a629c0 --- /dev/null +++ b/src/extend.rs @@ -0,0 +1,54 @@ +use std::{ + fs::File, + io::{self, Read}, + path::{Path, PathBuf}, +}; + +pub fn file_blake3(file: &Path) -> std::io::Result { + let mut blake3 = blake3::Hasher::new(); + let mut file = File::open(file)?; + let mut buffer = [0; 1024]; + loop { + let n = file.read(&mut buffer)?; + if n == 0 { + break; + } + blake3.update(&buffer[..n]); + } + Ok(blake3.finalize().to_string()) +} + +pub trait Blake3Path { + fn get_blake3(&self) -> io::Result; +} +impl Blake3Path for Path { + fn get_blake3(&self) -> io::Result { + if self.is_dir() { + // The default Error (PermissionDenied) is not very helpful when troubleshooting + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + format!("Path is a directory ({})", self.cute_path()), + )); + } + file_blake3(self) + } +} +impl Blake3Path for PathBuf { + fn get_blake3(&self) -> io::Result { + self.as_path().get_blake3() + } +} + +pub trait CutePath { + fn cute_path(&self) -> String; +} +impl CutePath for Path { + fn cute_path(&self) -> String { + self.to_str().unwrap().replace('\\', "/") + } +} +impl CutePath for PathBuf { + fn cute_path(&self) -> String { + self.as_path().cute_path() + } +} diff --git a/src/http_async.rs b/src/http_async.rs index a5055b3..3a506eb 100644 --- a/src/http_async.rs +++ b/src/http_async.rs @@ -7,6 +7,7 @@ use futures_util::StreamExt; use indicatif::ProgressBar; use reqwest::Client; +use crate::extend::*; use crate::misc; pub async fn download_file_progress( @@ -36,7 +37,7 @@ pub async fn download_file_progress( let msg = format!( "{}{} ({})", misc::prefix("downloading"), - misc::cute_path(path), + path.cute_path(), misc::human_readable_bytes(total_size) ); pb.println(&msg); diff --git a/src/iw4x.rs b/src/iw4x.rs index 6832312..56681da 100644 --- a/src/iw4x.rs +++ b/src/iw4x.rs @@ -1,3 +1,4 @@ +use crate::extend::*; use crate::github; use crate::global::*; use crate::http_async; @@ -24,7 +25,7 @@ pub async fn update(dir: &Path, cache: &mut structs::Cache) { println!( "{}{}", misc::prefix("downloading"), - misc::cute_path(&dir.join("iw4x.dll")) + dir.join("iw4x.dll").cute_path() ); http_async::download_file( &format!( diff --git a/src/main.rs b/src/main.rs index 0530e8e..bfada5d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod config; +mod extend; mod github; mod global; mod http_async; @@ -10,6 +11,7 @@ mod structs; #[cfg(test)] mod tests; +use extend::*; use global::*; use structs::*; @@ -219,13 +221,13 @@ async fn update_dir( let hash_local = hashes .get(file_name) .map(Cow::Borrowed) - .unwrap_or_else(|| Cow::Owned(misc::file_blake3(&file_path).unwrap())) + .unwrap_or_else(|| Cow::Owned(file_path.get_blake3().unwrap())) .to_string(); if hash_local != hash_remote { files_to_download.push(file.clone()); } else { - let msg = format!("{}{}", misc::prefix("checked"), misc::cute_path(&file_path)); + let msg = format!("{}{}", misc::prefix("checked"), file_path.cute_path()); pb.println(&msg); info!("{msg}"); hashes.insert(file_name.to_owned(), file.blake3.to_lowercase()); @@ -288,7 +290,7 @@ async fn update_dir( download_complete = true; } - let hash = misc::file_blake3(&file_path).unwrap(); + let hash = file_path.get_blake3().unwrap(); hashes.insert(file_name.to_owned(), hash.to_lowercase()); #[cfg(unix)] if file_name.ends_with(".exe") { @@ -388,14 +390,14 @@ async fn update( crate::println_info!( "{}{}", misc::prefix("removed"), - misc::cute_path(&file_path) + file_path.cute_path() ); if fs::remove_file(&file_path).is_err() { crate::println_error!( "{}Couldn't delete {}", misc::prefix("error"), - misc::cute_path(&file_path) + file_path.cute_path() ); } } @@ -430,20 +432,20 @@ async fn update( println!( "{}Couldn't delete {}", misc::prefix("error"), - misc::cute_path(&file_path) + file_path.cute_path() ); } else { - println!("{}{}", misc::prefix("removed"), misc::cute_path(&file_path)); + println!("{}{}", misc::prefix("removed"), file_path.cute_path()); } } else if file_path.is_dir() { if fs::remove_dir_all(&file_path).is_err() { println!( "{}Couldn't delete {}", misc::prefix("error"), - misc::cute_path(&file_path) + file_path.cute_path() ); } else { - println!("{}{}", misc::prefix("removed"), misc::cute_path(&file_path)); + println!("{}{}", misc::prefix("removed"), file_path.cute_path()); } } } diff --git a/src/misc.rs b/src/misc.rs index d8e7d4b..8bc26d1 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -1,26 +1,9 @@ +use std::{fs, path::Path}; + use indicatif::{ProgressBar, ProgressStyle}; -use std::{ - fs::{self, File}, - io::Read, - path::Path, -}; use crate::{global, structs}; -pub fn file_blake3(file: &Path) -> std::io::Result { - let mut blake3 = blake3::Hasher::new(); - let mut file = File::open(file)?; - let mut buffer = [0; 1024]; - loop { - let n = file.read(&mut buffer)?; - if n == 0 { - break; - } - blake3.update(&buffer[..n]); - } - Ok(blake3.finalize().to_string()) -} - pub fn stdin() -> String { let mut input = String::new(); std::io::stdin().read_line(&mut input).unwrap(); @@ -34,12 +17,6 @@ pub fn rev_to_int(rev: &str) -> u16 { .unwrap_or(0) } -pub fn fatal_error(error: &str) { - crate::println_error!("{}: {error}", prefix("error")); - stdin(); - std::process::exit(1); -} - pub fn human_readable_bytes(bytes: u64) -> String { let mut bytes = bytes as f64; let mut i = 0; @@ -62,10 +39,6 @@ pub fn pb_style_download(pb: &ProgressBar, state: bool) { pb.set_style(style.unwrap()); } -pub fn cute_path(path: &Path) -> String { - path.to_str().unwrap().replace('\\', "/") -} - #[cfg(unix)] pub fn is_program_in_path(program: &str) -> bool { std::env::var_os("PATH") diff --git a/src/tests.rs b/src/tests.rs index 3f615ff..b24d9ad 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -49,7 +49,7 @@ mod config { } mod misc { - use crate::{fs, misc, structs}; + use crate::{fs, misc, structs, Blake3Path}; use std::{fs::File, io::Write, path::Path}; #[test] @@ -64,7 +64,7 @@ mod misc { .unwrap() .write_all(b"alterware") .unwrap(); - let blake3 = misc::file_blake3(&path).unwrap(); + let blake3 = path.get_blake3().unwrap(); assert_eq!( blake3, "f18a70588a620f3a874120dbc2a41f49a0f44349c8a9c10c51f2f1c7bb678daa"