Compare commits
2 Commits
483d006181
...
ec59af73f2
Author | SHA1 | Date |
---|---|---|
|
ec59af73f2 | |
|
43a25a8ec9 |
|
@ -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")] // Define the argument without a short or long version
|
#[arg(name = "source", help = "First file of the comparision.")]
|
||||||
pub source: String,
|
pub source: String,
|
||||||
|
|
||||||
#[arg(name = "compare")] // Define the argument without a short or long version
|
#[arg(name = "compare", help = "Second file of the comparision.")]
|
||||||
pub compare: String,
|
pub compare: String,
|
||||||
|
|
||||||
#[arg(short, long)]
|
#[arg(short, long, help = "Column which is base of the comparision.")]
|
||||||
pub column: usize,
|
pub column: usize,
|
||||||
|
|
||||||
#[arg(short, long)]
|
#[arg(short, long, help = "Optional output filename.")]
|
||||||
pub output: Option<String>,
|
pub output: Option<String>,
|
||||||
|
|
||||||
#[arg(short, long, default_value_t = ';'.to_string())]
|
#[arg(short, long, default_value_t = ';'.to_string(), help = "Column separator.")]
|
||||||
pub delimiter: String,
|
pub delimiter: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,46 +9,27 @@ use super::args::MyArgs;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Params {
|
pub struct Params {
|
||||||
delimiter: String,
|
pub delimiter: String,
|
||||||
source: String,
|
pub source: String,
|
||||||
compared: String,
|
pub compared: String,
|
||||||
column: usize,
|
pub column: usize,
|
||||||
output: Option<String>,
|
pub output: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Params {
|
impl From<MyArgs> for Params {
|
||||||
pub fn new_from_matches(matches: MyArgs) -> Self {
|
|
||||||
Self {
|
fn from(matches: MyArgs) -> 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| x.to_string())
|
this.map(|x| ToString::to_string(&x))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
@ -88,7 +69,11 @@ pub fn write_to_file(filename: String, diff: Vec<CsvLine>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compare(reader: BufReader<File>, reader2: BufReader<File>, params: &Params) -> Vec<CsvLine> {
|
pub fn compare(
|
||||||
|
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| {
|
||||||
|
@ -105,8 +90,8 @@ pub fn compare(reader: BufReader<File>, reader2: BufReader<File>, params: &Param
|
||||||
})
|
})
|
||||||
.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);
|
||||||
|
@ -114,19 +99,22 @@ pub fn compare(reader: BufReader<File>, reader2: BufReader<File>, params: &Param
|
||||||
|
|
||||||
diff1.append(&mut diff2);
|
diff1.append(&mut diff2);
|
||||||
|
|
||||||
diff1
|
Ok(diff1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_diff(vec1: &[CsvLine], vec2: &[CsvLine], params: &Params) -> Vec<CsvLine> {
|
fn find_diff(vec1: &[CsvLine], vec2: &[CsvLine], params: &Params) -> Result<Vec<CsvLine>, String> {
|
||||||
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(¶ms.delimiter).collect();
|
||||||
let value = splitter[params.column];
|
if splitter.len() <= 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(¶ms.delimiter).collect();
|
||||||
let search = splitter_b[params.column()];
|
let search = splitter_b[params.column];
|
||||||
search == value
|
search == value
|
||||||
}),
|
}),
|
||||||
None
|
None
|
||||||
|
@ -137,7 +125,7 @@ fn find_diff(vec1: &[CsvLine], vec2: &[CsvLine], params: &Params) -> Vec<CsvLine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
diff
|
Ok(diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -167,7 +155,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, ¶ms);
|
let result: Vec<CsvLine> = compare(file1, file2, ¶ms).unwrap();
|
||||||
assert_eq!(3, result.len());
|
assert_eq!(3, result.len());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
42
src/main.rs
42
src/main.rs
|
@ -8,24 +8,44 @@ 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 mut params = Params::new_from_matches(args);
|
let params: Params = Params::from(args);
|
||||||
|
|
||||||
let file = File::open(params.source()).expect("Can't find source file");
|
let file: File = {
|
||||||
let file2 = File::open(params.compared()).expect("Cant't find compared file");
|
let this = File::open(¶ms.source);
|
||||||
|
match this {
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Can't find source file: {}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let file2 = {
|
||||||
|
let this = File::open(¶ms.compared);
|
||||||
|
match this {
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Cant't find compared file: {}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let reader = BufReader::new(file);
|
let reader: BufReader<File> = BufReader::new(file);
|
||||||
let reader2 = BufReader::new(file2);
|
let reader2: BufReader<File> = BufReader::new(file2);
|
||||||
|
|
||||||
let diff = compare::compare(reader, reader2, ¶ms);
|
let diff: Vec<compare::CsvLine> = match compare::compare(reader, reader2, ¶ms) {
|
||||||
|
Ok(d) => d,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("{e}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let option_string_ref = params.output_mut();
|
let option_string_ref: Option<String> = params.output;
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue