فهرست منبع

Added better error handling + extension handling

AvariceLHubris 1 ماه پیش
والد
کامیت
99f282f007
2فایلهای تغییر یافته به همراه46 افزوده شده و 24 حذف شده
  1. 3 3
      src/cli.rs
  2. 43 21
      src/main.rs

+ 3 - 3
src/cli.rs

@@ -1,4 +1,4 @@
-use std::ffi::OsString;
+use std::path::PathBuf;
 
 use clap::Parser;
 use clap::ValueEnum;
@@ -9,10 +9,10 @@ use clap::ValueEnum;
 pub struct Args {
 
     /// input file
-    pub input_file: OsString,
+    pub input_file: PathBuf,
 
     /// output file
-    pub output_file: Option<OsString>,
+    pub output_file: Option<PathBuf>,
 
     /// Whether to compress or extract.
     #[arg(short, value_enum, default_value = Mode::C)]

+ 43 - 21
src/main.rs

@@ -1,42 +1,55 @@
-use std::{ffi::OsString, io::Write};
+use std::io::Write;
 
+use anyhow::{Context, anyhow};
 use clap::Parser;
 use huffman::{cli, hufftree, storage};
 
-fn main() -> Result<(), std::io::Error> {
+fn main() -> Result<(), anyhow::Error> {
     let args = cli::Args::parse();
 
     let inputf = args.input_file;
     let outputf = args.output_file;
     let mode = args.mode;
 
+    if !inputf.exists() {
+        return Err(anyhow!("Input file did not exist."));
+    }
+
     let outputf = match outputf {
         Some(name) => name,
         None => match mode {
             cli::Mode::X => {
-                let mut temp = inputf
-                    .clone()
-                    .into_string()
-                    .expect("Not a valid input file name.");
-                if temp.ends_with(".z") {
-                    temp.pop();
-                    temp.pop();
+                if let Some(ext) = inputf.extension()
+                    && ext.eq("z")
+                {
+                    inputf.with_extension("")
                 } else {
-                    temp.push_str(".unhuffed");
+                    inputf.with_extension("unhuffed")
                 }
-                OsString::from(temp)
-            }
-            cli::Mode::C => {
-                let mut temp = inputf.clone();
-                temp.push(".z");
-                temp
             }
+            cli::Mode::C => match inputf.extension() {
+                // Check if we have an extension
+                Some(ext) => {
+                    // If so we retrieve it and then add to it a ".z"
+                    let ext = ext
+                        .to_str()
+                        .ok_or(anyhow!("Input file path was not valid unicode."))?;
+                    let new_extension = ext.to_string() + ".z";
+
+                    inputf.with_extension(new_extension)
+                }
+                // Otherwise just use the native syntax for add '.z'
+                None => inputf.with_extension(".z"),
+            },
         },
     };
 
     let working_directory = std::path::Path::new(".");
     let inputf = working_directory.join(inputf);
-    let in_size = inputf.metadata().unwrap().len();
+    let in_size = inputf
+        .metadata()
+        .context("Could not get the input file's metadata")?
+        .len();
 
     let outputf = working_directory.join(outputf);
     let mut outputf = std::fs::File::create(outputf)?;
@@ -49,8 +62,13 @@ fn main() -> Result<(), std::io::Error> {
             let decoded_text = huffman::storage::read_tree_and_text(&mut &inputf[..]);
             println!("Decoded!");
 
-            outputf.write_all(decoded_text.as_bytes()).unwrap();
-            let out_size = outputf.metadata().unwrap().len();
+            outputf
+                .write_all(decoded_text.as_bytes())
+                .context("Could not write decoded text to output file.")?;
+            let out_size = outputf
+                .metadata()
+                .context("Could not get the input file's metadata")?
+                .len();
             println!("Stored: {} bytes.", out_size);
             println!(
                 "Compression Ratio: {:.2}.",
@@ -59,7 +77,8 @@ fn main() -> Result<(), std::io::Error> {
         }
 
         cli::Mode::C => {
-            let inputf = std::fs::read_to_string(inputf)?;
+            let inputf =
+                std::fs::read_to_string(inputf).context("Could not read input file to string.")?;
             println!("Read: {} bytes.", in_size);
             let char_f = huffman::hufftree::base::get_char_frequencies(&inputf);
 
@@ -68,7 +87,10 @@ fn main() -> Result<(), std::io::Error> {
 
             storage::store_tree_and_text(canonical_tree, &mut outputf, &inputf)
                 .expect("Could not store the tree and text.");
-            let out_size = outputf.metadata().unwrap().len();
+            let out_size = outputf
+                .metadata()
+                .context("Could not get the input file's metadata")?
+                .len();
             println!("Stored: {} bytes.", out_size);
             println!(
                 "Compression Ratio: {:.2}.",