refactor code: move compare_lines into lines.rs
This commit is contained in:
parent
14ae7c6bf0
commit
0855555b05
3 changed files with 46 additions and 38 deletions
14
readme.md
14
readme.md
|
@ -2,6 +2,14 @@
|
||||||
|
|
||||||
Ndiff is an educational Rust rewrite of the [diff](https://linux.die.net/man/1/diff) program.
|
Ndiff is an educational Rust rewrite of the [diff](https://linux.die.net/man/1/diff) program.
|
||||||
|
|
||||||
Of course, it's no way near as featured as
|
Of course, it's no way near as featured as
|
||||||
the [diff](https://linux.die.net/man/1/diff) command,
|
the [diff](https://linux.die.net/man/1/diff) command,
|
||||||
since it's utility is to learn Rust concepts by completing a simple project.
|
since it's utility is to learn Rust concepts by completing a simple project.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
You may install and play around with the program using the command line:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo install --git https://github.com/dnutiu/ndiff
|
||||||
|
```
|
38
src/line.rs
38
src/line.rs
|
@ -1,16 +1,17 @@
|
||||||
use std::{fmt};
|
use itertools::Itertools;
|
||||||
|
use std::fmt;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct MissingLineIndicator {
|
pub(crate) struct MissingLineIndicator {
|
||||||
pub value: String
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MissingLineIndicator {
|
impl Default for MissingLineIndicator {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
MissingLineIndicator{
|
MissingLineIndicator {
|
||||||
value: String::from("<missing line>")
|
value: String::from("<missing line>"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +29,6 @@ pub(crate) enum Line {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Line {
|
impl Line {
|
||||||
|
|
||||||
/// Prints the line to stdout
|
/// Prints the line to stdout
|
||||||
pub fn print(&self) {
|
pub fn print(&self) {
|
||||||
match self {
|
match self {
|
||||||
|
@ -72,4 +72,30 @@ impl fmt::Display for Line {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compares the lines of two texts.
|
||||||
|
///
|
||||||
|
/// It returns a [`Vec<Line>`]
|
||||||
|
pub fn compare_lines(left_text: &str, right_text: &str) -> Vec<Line> {
|
||||||
|
left_text
|
||||||
|
.lines()
|
||||||
|
.map(String::from)
|
||||||
|
.zip_longest(right_text.lines().map(String::from))
|
||||||
|
.enumerate()
|
||||||
|
.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 {
|
||||||
|
Line::DifferingLine(line_number as i32 + 1, left, right)
|
||||||
|
} else {
|
||||||
|
Line::MatchedLine(line_number as i32 + 1, left)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
32
src/main.rs
32
src/main.rs
|
@ -1,46 +1,20 @@
|
||||||
use crate::line::{Line, MissingLineIndicator};
|
use crate::line::Line;
|
||||||
use itertools::Itertools;
|
|
||||||
use std::fs::read_to_string;
|
use std::fs::read_to_string;
|
||||||
|
|
||||||
mod line;
|
mod line;
|
||||||
|
|
||||||
/// Gets the lines of two given texts
|
|
||||||
///
|
|
||||||
/// 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_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 {
|
|
||||||
Line::DifferingLine(line_number as i32 + 1, left, right)
|
|
||||||
} else {
|
|
||||||
Line::MatchedLine(line_number as i32 + 1, left)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let left_file = read_to_string("a.txt").expect("Left file not found");
|
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 right_file = read_to_string("b.txt").expect("Right file not found");
|
||||||
|
|
||||||
let lines: Vec<Line> = get_lines(&left_file, &right_file);
|
let lines: Vec<Line> = line::compare_lines(&left_file, &right_file);
|
||||||
|
|
||||||
let mut differences_counter: i32 = 0;
|
let mut differences_counter: i32 = 0;
|
||||||
for line in lines.iter() {
|
for line in lines.iter() {
|
||||||
line.print();
|
line.print();
|
||||||
match line {
|
match line {
|
||||||
Line::MatchedLine(_, _) => {}
|
Line::MatchedLine(_, _) => {}
|
||||||
Line::DifferingLine(_, _, _) => {
|
Line::DifferingLine(_, _, _) => differences_counter += 1,
|
||||||
differences_counter += 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
|
|
Loading…
Reference in a new issue