refactor code

This commit is contained in:
Denis-Cosmin Nutiu 2024-10-24 19:04:48 +03:00
parent 9e335ab0a7
commit e5ecc46c40
2 changed files with 75 additions and 29 deletions

View file

@ -2,18 +2,55 @@ use std::fmt;
use std::fmt::Formatter; use std::fmt::Formatter;
use std::ops::Deref; use std::ops::Deref;
pub trait Line: fmt::Display {
fn is_difference(&self) -> bool;
}
/// Line represents a non-differing line.
pub(crate) struct MatchedLine {
line_number: i32,
line: String,
}
impl MatchedLine {
/// Constructs a new Line instance
pub fn new(line_number: i32, line: String) -> MatchedLine {
MatchedLine { line_number, line }
}
/// get_line returns the line.
pub fn get_line(&self) -> &String {
&self.line
}
}
impl fmt::Display for MatchedLine {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, r#"{}. {}"#, self.line_number, self.get_line(),)
.expect("Failed to write MatchedLine");
writeln!(f)
}
}
impl Line for MatchedLine {
fn is_difference(&self) -> bool {
false
}
}
/// A line difference is represented by the Difference struct. /// A line difference is represented by the Difference struct.
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct Difference { pub(crate) struct DifferingLine {
line_number: i32, line_number: i32,
missing_line_indicator: String, missing_line_indicator: String,
left_line: String, left_line: String,
right_line: String, right_line: String,
} }
impl Difference { impl DifferingLine {
pub fn new(line_number: i32, left_line: String, right_line: String) -> Difference { /// Constructs a new difference instance.
Difference { pub fn new(line_number: i32, left_line: String, right_line: String) -> DifferingLine {
DifferingLine {
line_number, line_number,
missing_line_indicator: String::from("<missing line>"), missing_line_indicator: String::from("<missing line>"),
left_line: left_line.into(), left_line: left_line.into(),
@ -40,20 +77,24 @@ impl Difference {
} }
} }
/// Implements the display trait. impl fmt::Display for DifferingLine {
impl fmt::Display for Difference {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!( write!(
f, f,
r#"Line: {}. r#" - {}
< {} {}. ----
---- + {}"#,
> {}
"#,
self.line_number,
self.left_line(), self.left_line(),
self.line_number,
self.right_line() self.right_line()
) )
.expect("Failed to write DifferingLines");
writeln!(f)
}
}
impl Line for DifferingLine {
fn is_difference(&self) -> bool {
true
} }
} }

View file

@ -1,41 +1,46 @@
use crate::difference::Difference; use crate::line::{DifferingLine, Line, MatchedLine};
use itertools::Itertools; use itertools::Itertools;
use std::fs::read_to_string; use std::fs::read_to_string;
use std::ops::Deref;
mod difference; mod line;
/// Gets the differences of lines that differ in the given text. /// Gets the lines of two given texts
/// ///
/// It returns a [`Vec<Difference>`] /// It returns a [`Vec<Box<dyn Line>>`]
fn get_differences(left_text: &String, right_text: &String) -> Vec<Difference> { fn get_lines(left_text: &String, right_text: &String) -> Vec<Box<dyn Line>> {
left_text left_text
.lines() .lines()
.map(String::from) .map(String::from)
.zip_longest(right_text.lines().map(String::from)) .zip_longest(right_text.lines().map(String::from))
.enumerate() .enumerate()
.filter_map(|(line, item)| -> Option<Difference> { .map(|(line, item)| -> Box<dyn Line> {
let left = item.clone().left().unwrap_or(String::from("")); let left = item.clone().left().unwrap_or(String::from(""));
let right = item.right().unwrap_or(String::from("")); let right = item.right().unwrap_or(String::from(""));
if left != right { if left != right {
Some(Difference::new(line as i32 + 1, left, right)) Box::new(DifferingLine::new(line as i32 + 1, left, right))
} else { } else {
return None; Box::new(MatchedLine::new(line as i32 + 1, left))
} }
}) })
.collect() .collect()
} }
fn main() { fn main() {
let left_file = let left_file = read_to_string("a.txt").expect("Left file not found");
read_to_string("a.txt").expect("Left file not found"); let right_file = read_to_string("b.txt").expect("Right file not found");
let right_file =
read_to_string("b.txt").expect("Right file not found");
let res: Vec<Difference> = get_differences(&left_file, &right_file); let lines: Vec<Box<dyn Line>> = get_lines(&left_file, &right_file);
for diff in res.iter() { let mut differences_counter: i32 = 0;
print!("{diff}") for line in lines.iter() {
let line = line.deref();
print!("{}", line);
if line.is_difference() {
differences_counter += 1;
}
} }
println!("Found {} differences.", res.len()) println!();
println!("Found {} differences.", differences_counter);
} }