From 7f5961856c243b787fa85270f21cb49effdfb6c4 Mon Sep 17 00:00:00 2001 From: Daniil-Golikov Date: Fri, 13 Oct 2023 16:34:23 +1100 Subject: [PATCH 1/3] Autodetect input type and handle arguments - Implement input type autodetection - Add FFT as a CLI argument - Check the number of provided arguments --- brro-compressor/src/main.rs | 64 ++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/brro-compressor/src/main.rs b/brro-compressor/src/main.rs index 06b32ae..bb8a042 100644 --- a/brro-compressor/src/main.rs +++ b/brro-compressor/src/main.rs @@ -1,3 +1,5 @@ +use std::error::Error; +use std::fs; use brro_compressor::compressor::Compressor; use brro_compressor::data::CompressedStream; use brro_compressor::optimizer; @@ -5,22 +7,42 @@ use brro_compressor::types::metric_tag::MetricTag; use brro_compressor::utils::reader; use brro_compressor::utils::writer; use clap::{arg, command, Parser}; -use log::debug; +use log::{debug, error}; use std::path::Path; use std::path::PathBuf; /// Processes the given input based on the provided arguments. -/// If `arguments.directory` is true, it processes all files in the directory. -/// Otherwise, it processes the individual file. -fn process_args(arguments: &Args) { +fn process_args(arguments: &Args) -> Result<(), Box> { + + // Create a vector of boolean values from the argument flags. + // Then, count how many of these flags are set to true. + let count = vec![arguments.noop, arguments.constant, arguments.fft] + .iter() + .filter(|&&x| x) + .count(); + + if count > 1 { + return Err("Multiple compressors are set to true. Please specify only one.".into()); + } + + let metadata = fs::metadata(&arguments.input)?; + + // If the input path points to a single file + if metadata.is_file() { + debug!("Target is a file"); + process_single_file(arguments); + } // If the input path points to a directory - if arguments.directory { + else if metadata.is_dir() { + debug!("Target is a directory"); process_directory(arguments); } - // If the input path points to a single file + // If the input path is neither a file nor a directory else { - process_single_file(arguments); + return Err("The provided path is neither a file nor a directory.".into()); } + + Ok(()) } /// Processes all files in a given directory. @@ -66,13 +88,14 @@ fn compress_data(vec: &Vec, tag: &MetricTag, arguments: &Args) -> Vec { let optimizer_results_f: Vec = optimizer_results.iter().map(|&x| x as f64).collect(); let mut cs = CompressedStream::new(); - if arguments.constant { - cs.compress_chunk_with(&optimizer_results_f, Compressor::Constant); - cs.to_bytes() - } else { - cs.compress_chunk_with(&optimizer_results_f, Compressor::Noop); - cs.to_bytes() - } + let compressor = match arguments { + _ if arguments.constant => Compressor::Constant, + _ if arguments.fft => Compressor::FFT, + _ => Compressor::Noop, + }; + + cs.compress_chunk_with(&optimizer_results_f, compressor); + cs.to_bytes() } /// Writes the compressed data to the specified path. @@ -88,9 +111,6 @@ struct Args { /// input file input: PathBuf, - #[arg(short, action)] - directory: bool, - /// Forces Noop compressor #[arg(long, action)] noop: bool, @@ -98,11 +118,19 @@ struct Args { /// Forces Constant compressor #[arg(long, action)] constant: bool, + + /// Forces Constant compressor + #[arg(long, action)] + fft: bool, + } fn main() { env_logger::init(); let arguments = Args::parse(); debug!("{:?}", arguments); - process_args(&arguments); + + if let Err(e) = process_args(&arguments) { + error!("Error processing arguments: {}", e); + } } From 5dba81065c30d306fbb50636869bc86dcc02d456 Mon Sep 17 00:00:00 2001 From: Daniil-Golikov Date: Fri, 13 Oct 2023 16:34:23 +1100 Subject: [PATCH 2/3] Autodetect input type and handle arguments - Implement input type autodetection - Add FFT as a CLI argument - Check the number of provided arguments - Better error handling --- brro-compressor/src/main.rs | 89 +++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/brro-compressor/src/main.rs b/brro-compressor/src/main.rs index 06b32ae..a8d6e77 100644 --- a/brro-compressor/src/main.rs +++ b/brro-compressor/src/main.rs @@ -1,3 +1,5 @@ +use std::error::Error; +use std::fs; use brro_compressor::compressor::Compressor; use brro_compressor::data::CompressedStream; use brro_compressor::optimizer; @@ -5,35 +7,55 @@ use brro_compressor::types::metric_tag::MetricTag; use brro_compressor::utils::reader; use brro_compressor::utils::writer; use clap::{arg, command, Parser}; -use log::debug; +use log::{debug, error}; use std::path::Path; use std::path::PathBuf; /// Processes the given input based on the provided arguments. -/// If `arguments.directory` is true, it processes all files in the directory. -/// Otherwise, it processes the individual file. -fn process_args(arguments: &Args) { - // If the input path points to a directory - if arguments.directory { - process_directory(arguments); +fn process_args(arguments: &Args) -> Result<(), Box> { + + // Create a vector of boolean values from the argument flags. + // Then, count how many of these flags are set to true. + let count = vec![arguments.noop, arguments.constant, arguments.fft] + .iter() + .filter(|&&x| x) + .count(); + + if count > 1 { + return Err("Multiple compressors are set to true. Please specify only one.".into()); } + + let metadata = fs::metadata(&arguments.input)?; + // If the input path points to a single file + if metadata.is_file() { + debug!("Target is a file"); + process_single_file(arguments)?; + } + // If the input path points to a directory + else if metadata.is_dir() { + debug!("Target is a directory"); + process_directory(arguments)?; + } + // If the input path is neither a file nor a directory else { - process_single_file(arguments); + return Err("The provided path is neither a file nor a directory.".into()); } + + Ok(()) } /// Processes all files in a given directory. -fn process_directory(arguments: &Args) { +fn process_directory(arguments: &Args) -> Result<(), std::io::Error> { let new_name = format!( "{}-compressed", arguments.input.file_name().unwrap().to_string_lossy() ); let base_dir = arguments.input.with_file_name(new_name); - writer::initialize_directory(&base_dir).expect("Failed to initialize directory"); + writer::initialize_directory(&base_dir)?; let files = - reader::stream_reader(&arguments.input).expect("Failed to read files from directory"); + reader::stream_reader(&arguments.input)?; for (index, data) in files.contents.iter().enumerate() { let (vec_data, tag) = data; @@ -41,13 +63,14 @@ fn process_directory(arguments: &Args) { let file_name = writer::replace_extension(&files.names[index], "bin"); let new_path = base_dir.join(&file_name); - write_compressed_data_to_path(&compressed_data, &new_path); + write_compressed_data_to_path(&compressed_data, &new_path)?; } + Ok(()) } /// Processes a single file. -fn process_single_file(arguments: &Args) { - let (vec, tag) = reader::read_file(&arguments.input).expect("Failed to read file"); +fn process_single_file(arguments: &Args) -> Result<(), std::io::Error> { + let (vec, tag) = reader::read_file(&arguments.input)?; let compressed_data = compress_data(&vec, &tag, arguments); if let Some(filename_osstr) = arguments.input.file_name() { @@ -55,9 +78,10 @@ fn process_single_file(arguments: &Args) { let new_filename_string = writer::replace_extension(&filename_str.to_string(), "bin"); let new_path = arguments.input.parent().unwrap().join(new_filename_string); - write_compressed_data_to_path(&compressed_data, &new_path); + write_compressed_data_to_path(&compressed_data, &new_path)?; } } + Ok(()) } /// Compresses the data based on the provided tag and arguments. @@ -66,20 +90,22 @@ fn compress_data(vec: &Vec, tag: &MetricTag, arguments: &Args) -> Vec { let optimizer_results_f: Vec = optimizer_results.iter().map(|&x| x as f64).collect(); let mut cs = CompressedStream::new(); - if arguments.constant { - cs.compress_chunk_with(&optimizer_results_f, Compressor::Constant); - cs.to_bytes() - } else { - cs.compress_chunk_with(&optimizer_results_f, Compressor::Noop); - cs.to_bytes() - } + let compressor = match arguments { + _ if arguments.constant => Compressor::Constant, + _ if arguments.fft => Compressor::FFT, + _ => Compressor::Noop, + }; + + cs.compress_chunk_with(&optimizer_results_f, compressor); + cs.to_bytes() } /// Writes the compressed data to the specified path. -fn write_compressed_data_to_path(compressed: &[u8], path: &Path) { +fn write_compressed_data_to_path(compressed: &[u8], path: &Path) -> Result<(), std::io::Error>{ let mut file = - writer::create_streaming_writer(path).expect("Failed to create a streaming writer"); - writer::write_data_to_stream(&mut file, compressed).expect("Failed to write compressed data"); + writer::create_streaming_writer(path)?; + writer::write_data_to_stream(&mut file, compressed)?; + Ok(()) } #[derive(Parser, Default, Debug)] @@ -88,9 +114,6 @@ struct Args { /// input file input: PathBuf, - #[arg(short, action)] - directory: bool, - /// Forces Noop compressor #[arg(long, action)] noop: bool, @@ -98,11 +121,19 @@ struct Args { /// Forces Constant compressor #[arg(long, action)] constant: bool, + + /// Forces Constant compressor + #[arg(long, action)] + fft: bool, + } fn main() { env_logger::init(); let arguments = Args::parse(); debug!("{:?}", arguments); - process_args(&arguments); + + if let Err(e) = process_args(&arguments) { + error!("{}", e); + } } From cb43d3de6693204e5e4bfc078a0b2a943732c2bb Mon Sep 17 00:00:00 2001 From: Daniil-Golikov Date: Tue, 17 Oct 2023 09:50:16 +1100 Subject: [PATCH 3/3] Fixed error handling after the merge with main --- brro-compressor/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brro-compressor/src/main.rs b/brro-compressor/src/main.rs index fee507d..8432e08 100644 --- a/brro-compressor/src/main.rs +++ b/brro-compressor/src/main.rs @@ -85,7 +85,7 @@ fn process_single_file(arguments: &Args) -> Result<(), std::io::Error> { let new_filename_string = writer::replace_extension(&filename_str.to_string(), "bro"); let new_path = arguments.input.parent().unwrap().join(new_filename_string); - write_compressed_data_to_path(&compressed_data, &new_path); + write_compressed_data_to_path(&compressed_data, &new_path)?; } } }