Compare commits

..

No commits in common. "ec59af73f2b5f8d911d2191891bda1dab89c295f" and "483d006181cbbb717459b7be69fbaae46ef372a1" have entirely different histories.

3 changed files with 56 additions and 64 deletions

View File

@ -3,18 +3,18 @@ use clap::Parser;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
pub struct MyArgs { pub struct MyArgs {
#[arg(name = "source", help = "First file of the comparision.")] #[arg(name = "source")] // Define the argument without a short or long version
pub source: String, pub source: String,
#[arg(name = "compare", help = "Second file of the comparision.")] #[arg(name = "compare")] // Define the argument without a short or long version
pub compare: String, pub compare: String,
#[arg(short, long, help = "Column which is base of the comparision.")] #[arg(short, long)]
pub column: usize, pub column: usize,
#[arg(short, long, help = "Optional output filename.")] #[arg(short, long)]
pub output: Option<String>, pub output: Option<String>,
#[arg(short, long, default_value_t = ';'.to_string(), help = "Column separator.")] #[arg(short, long, default_value_t = ';'.to_string())]
pub delimiter: String, pub delimiter: String,
} }

View File

@ -9,27 +9,46 @@ use super::args::MyArgs;
#[derive(Debug)] #[derive(Debug)]
pub struct Params { pub struct Params {
pub delimiter: String, delimiter: String,
pub source: String, source: String,
pub compared: String, compared: String,
pub column: usize, column: usize,
pub output: Option<String>, output: Option<String>,
} }
impl From<MyArgs> for Params { impl Params {
pub fn new_from_matches(matches: MyArgs) -> Self {
fn from(matches: MyArgs) -> Self { Self {
Params {
delimiter: matches.delimiter, delimiter: matches.delimiter,
source: matches.source, source: matches.source,
compared: matches.compare, compared: matches.compare,
column: matches.column, column: matches.column,
output: { output: {
let this = matches.output; let this = matches.output;
this.map(|x| ToString::to_string(&x)) this.map(|x| x.to_string())
}, },
} }
} }
pub fn delimiter(&self) -> &String {
&self.delimiter
}
pub fn source(&self) -> &String {
&self.source
}
pub fn compared(&self) -> &String {
&self.compared
}
pub fn column(&self) -> usize {
self.column
}
pub fn output_mut(&mut self) -> &Option<String> {
&self.output
}
} }
pub struct CsvLine { pub struct CsvLine {
@ -69,11 +88,7 @@ pub fn write_to_file(filename: String, diff: Vec<CsvLine>) {
} }
} }
pub fn compare( pub fn compare(reader: BufReader<File>, reader2: BufReader<File>, params: &Params) -> Vec<CsvLine> {
reader: BufReader<File>,
reader2: BufReader<File>,
params: &Params,
) -> Result<Vec<CsvLine>, String> {
let vec1: Vec<CsvLine> = reader let vec1: Vec<CsvLine> = reader
.lines() .lines()
.map(|line| { .map(|line| {
@ -90,8 +105,8 @@ pub fn compare(
}) })
.collect(); .collect();
let mut diff1: Vec<CsvLine> = find_diff(&vec1, &vec2, params)?; let mut diff1: Vec<CsvLine> = find_diff(&vec1, &vec2, params);
let mut diff2: Vec<CsvLine> = find_diff(&vec2, &vec1, params)?; let mut diff2: Vec<CsvLine> = find_diff(&vec2, &vec1, params);
if params.output.is_none() { if params.output.is_none() {
print_lines(&diff1, &diff2, params); print_lines(&diff1, &diff2, params);
@ -99,22 +114,19 @@ pub fn compare(
diff1.append(&mut diff2); diff1.append(&mut diff2);
Ok(diff1) diff1
} }
fn find_diff(vec1: &[CsvLine], vec2: &[CsvLine], params: &Params) -> Result<Vec<CsvLine>, String> { fn find_diff(vec1: &[CsvLine], vec2: &[CsvLine], params: &Params) -> Vec<CsvLine> {
let mut diff: Vec<CsvLine> = Vec::new(); let mut diff: Vec<CsvLine> = Vec::new();
for i in vec1.iter() { for i in vec1.iter() {
let splitter: Vec<&str> = i.line.split(&params.delimiter).collect(); let splitter: Vec<&str> = i.line.split(params.delimiter()).collect();
if splitter.len() <= params.column { let value = splitter[params.column];
return Err("Column out of bound".to_string());
}
let value: &str = splitter[params.column];
let found = !matches!( let found = !matches!(
vec2.iter().position(|r| { vec2.iter().position(|r| {
let splitter_b: Vec<&str> = r.line.split(&params.delimiter).collect(); let splitter_b: Vec<&str> = r.line.split(params.delimiter()).collect();
let search = splitter_b[params.column]; let search = splitter_b[params.column()];
search == value search == value
}), }),
None None
@ -125,7 +137,7 @@ fn find_diff(vec1: &[CsvLine], vec2: &[CsvLine], params: &Params) -> Result<Vec<
} }
} }
Ok(diff) diff
} }
#[cfg(test)] #[cfg(test)]
@ -155,7 +167,7 @@ mod test {
column: 1, column: 1,
output: Some("./assets/result.csv".to_owned()), output: Some("./assets/result.csv".to_owned()),
}; };
let result: Vec<CsvLine> = compare(file1, file2, &params).unwrap(); let result: Vec<CsvLine> = compare(file1, file2, &params);
assert_eq!(3, result.len()); assert_eq!(3, result.len());
} }
} }

View File

@ -8,44 +8,24 @@ use csv::compare;
use crate::csv::args::MyArgs; use crate::csv::args::MyArgs;
use crate::csv::compare::{write_to_file, Params}; use crate::csv::compare::{write_to_file, Params};
/// # Panics
///
/// Panics if delimter is set wrong and column to compare
/// is not available.
fn main() { fn main() {
let args = MyArgs::parse(); let args = MyArgs::parse();
let params: Params = Params::from(args); let mut params = Params::new_from_matches(args);
let file: File = { let file = File::open(params.source()).expect("Can't find source file");
let this = File::open(&params.source); let file2 = File::open(params.compared()).expect("Cant't find compared file");
match this {
Ok(file) => file,
Err(e) => {
eprintln!("Can't find source file: {}", e);
return;
}
}
};
let file2 = {
let this = File::open(&params.compared);
match this {
Ok(file) => file,
Err(e) => {
eprintln!("Cant't find compared file: {}", e);
return;
}
}
};
let reader: BufReader<File> = BufReader::new(file); let reader = BufReader::new(file);
let reader2: BufReader<File> = BufReader::new(file2); let reader2 = BufReader::new(file2);
let diff: Vec<compare::CsvLine> = match compare::compare(reader, reader2, &params) { let diff = compare::compare(reader, reader2, &params);
Ok(d) => d,
Err(e) => {
eprintln!("{e}");
return;
}
};
let option_string_ref: Option<String> = params.output; let option_string_ref = params.output_mut();
if let Some(string_ref) = option_string_ref { if let Some(string_ref) = option_string_ref {
write_to_file(string_ref.clone(), diff); write_to_file(string_ref.clone(), diff);
} }