refactor using Enum
This commit is contained in:
parent
8ad7f5c305
commit
283efb0b1f
2 changed files with 54 additions and 101 deletions
125
src/line.rs
125
src/line.rs
|
@ -1,100 +1,51 @@
|
|||
use std::fmt;
|
||||
use std::fmt::Formatter;
|
||||
use std::ops::Deref;
|
||||
|
||||
pub trait Line: fmt::Display {
|
||||
fn is_differing(&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_differing(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// A line difference is represented by the Difference struct.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct DifferingLine {
|
||||
line_number: i32,
|
||||
missing_line_indicator: String,
|
||||
left_line: String,
|
||||
right_line: String,
|
||||
pub(crate) struct MissingLineIndicator {
|
||||
pub value: String
|
||||
}
|
||||
|
||||
impl DifferingLine {
|
||||
/// Constructs a new difference instance.
|
||||
pub fn new(line_number: i32, left_line: String, right_line: String) -> DifferingLine {
|
||||
DifferingLine {
|
||||
line_number,
|
||||
missing_line_indicator: String::from("<missing line>"),
|
||||
left_line: left_line.into(),
|
||||
right_line: right_line.into(),
|
||||
impl Default for MissingLineIndicator {
|
||||
fn default() -> Self {
|
||||
MissingLineIndicator{
|
||||
value: String::from("<missing line>")
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the left line of the difference.
|
||||
#[allow(dead_code)]
|
||||
pub fn left_line(&self) -> &String {
|
||||
if self.left_line.deref() == "" {
|
||||
return &self.missing_line_indicator;
|
||||
}
|
||||
&self.left_line
|
||||
}
|
||||
|
||||
/// Returns the right line of the difference.
|
||||
#[allow(dead_code)]
|
||||
pub fn right_line(&self) -> &String {
|
||||
if self.right_line.deref() == "" {
|
||||
return &self.missing_line_indicator;
|
||||
}
|
||||
&self.right_line
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DifferingLine {
|
||||
/// The line enum models a file line.
|
||||
pub(crate) enum Line {
|
||||
/// MatchedLine represents a line that matches when comparing the files.
|
||||
///
|
||||
/// MatchedLine(line_number, line)
|
||||
MatchedLine(i32, String),
|
||||
/// DifferingLine represents a line that does not match its counterpart line.
|
||||
///
|
||||
/// DifferingLine(line_number, left_line, right_line)
|
||||
DifferingLine(i32, String, String),
|
||||
}
|
||||
|
||||
impl fmt::Display for Line {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
r#" - {}
|
||||
{}. ----
|
||||
+ {}"#,
|
||||
self.left_line(),
|
||||
self.line_number,
|
||||
self.right_line()
|
||||
)
|
||||
.expect("Failed to write DifferingLines");
|
||||
writeln!(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Line for DifferingLine {
|
||||
fn is_differing(&self) -> bool {
|
||||
true
|
||||
match self {
|
||||
Line::MatchedLine(line_number, line) => {
|
||||
write!(f, r#"{}. {}"#, line_number, line,).expect("Failed to write MatchedLine");
|
||||
writeln!(f)
|
||||
}
|
||||
Line::DifferingLine(line_number, left_line, right_line) => {
|
||||
write!(
|
||||
f,
|
||||
r#" - {left_line}
|
||||
{line_number}. ----
|
||||
+ {right_line}"#,
|
||||
left_line = left_line,
|
||||
line_number = line_number,
|
||||
right_line = right_line
|
||||
)
|
||||
.expect("Failed to write DifferingLines");
|
||||
writeln!(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
src/main.rs
28
src/main.rs
|
@ -1,27 +1,27 @@
|
|||
use crate::line::{DifferingLine, Line, MatchedLine};
|
||||
use crate::line::{Line, MissingLineIndicator};
|
||||
use itertools::Itertools;
|
||||
use std::fs::read_to_string;
|
||||
use std::ops::Deref;
|
||||
|
||||
mod line;
|
||||
|
||||
/// Gets the lines of two given texts
|
||||
///
|
||||
/// It returns a [`Vec<Box<dyn Line>>`]
|
||||
fn get_lines(left_text: &String, right_text: &String) -> Vec<Box<dyn Line>> {
|
||||
/// It returns a [`Vec<Box<Line>>`]
|
||||
fn get_lines(left_text: &String, right_text: &String) -> Vec<Line> {
|
||||
left_text
|
||||
.lines()
|
||||
.map(String::from)
|
||||
.zip_longest(right_text.lines().map(String::from))
|
||||
.enumerate()
|
||||
.map(|(line, item)| -> Box<dyn Line> {
|
||||
let left = item.clone().left().unwrap_or(String::from(""));
|
||||
let right = item.right().unwrap_or(String::from(""));
|
||||
.map(|(line_number, item)| -> Line {
|
||||
let missing_line_indicator: MissingLineIndicator = Default::default();
|
||||
let left = item.clone().left().unwrap_or(missing_line_indicator.value.clone());
|
||||
let right = item.right().unwrap_or(missing_line_indicator.value);
|
||||
|
||||
if left != right {
|
||||
Box::new(DifferingLine::new(line as i32 + 1, left, right))
|
||||
Line::DifferingLine(line_number as i32 + 1, left, right)
|
||||
} else {
|
||||
Box::new(MatchedLine::new(line as i32 + 1, left))
|
||||
Line::MatchedLine(line_number as i32 + 1, left)
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
|
@ -31,14 +31,16 @@ fn main() {
|
|||
let left_file = read_to_string("a.txt").expect("Left file not found");
|
||||
let right_file = read_to_string("b.txt").expect("Right file not found");
|
||||
|
||||
let lines: Vec<Box<dyn Line>> = get_lines(&left_file, &right_file);
|
||||
let lines: Vec<Line> = get_lines(&left_file, &right_file);
|
||||
|
||||
let mut differences_counter: i32 = 0;
|
||||
for line in lines.iter() {
|
||||
let line = line.deref();
|
||||
print!("{}", line);
|
||||
if line.is_differing() {
|
||||
differences_counter += 1;
|
||||
match line {
|
||||
Line::MatchedLine(_, _) => {}
|
||||
Line::DifferingLine(_, _, _) => {
|
||||
differences_counter += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
println!();
|
||||
|
|
Loading…
Reference in a new issue