From 283efb0b1f49053944b7a46818754d43fa5f2a42 Mon Sep 17 00:00:00 2001 From: Denis Nutiu Date: Thu, 24 Oct 2024 21:27:27 +0300 Subject: [PATCH] refactor using Enum --- src/line.rs | 127 ++++++++++++++++------------------------------------ src/main.rs | 28 ++++++------ 2 files changed, 54 insertions(+), 101 deletions(-) diff --git a/src/line.rs b/src/line.rs index 3def30f..9a1fc06 100644 --- a/src/line.rs +++ b/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(""), - left_line: left_line.into(), - right_line: right_line.into(), +impl Default for MissingLineIndicator { + fn default() -> Self { + MissingLineIndicator{ + value: String::from("") } } - - /// 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) + 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) + } + } } -} - -impl Line for DifferingLine { - fn is_differing(&self) -> bool { - true - } -} +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 87d9077..190421f 100644 --- a/src/main.rs +++ b/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>`] -fn get_lines(left_text: &String, right_text: &String) -> Vec> { +/// It returns a [`Vec>`] +fn get_lines(left_text: &String, right_text: &String) -> Vec { left_text .lines() .map(String::from) .zip_longest(right_text.lines().map(String::from)) .enumerate() - .map(|(line, item)| -> Box { - 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> = get_lines(&left_file, &right_file); + let lines: Vec = 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!();