From e2521179b7b016859278ab9ee4b444616236542f Mon Sep 17 00:00:00 2001 From: Denis-Cosmin NUTIU Date: Thu, 24 Oct 2024 17:20:52 +0300 Subject: [PATCH] initial commit --- .gitignore | 1 + .idea/.gitignore | 8 +++++++ .idea/modules.xml | 8 +++++++ .idea/ndiff.iml | 11 +++++++++ .idea/vcs.xml | 6 +++++ Cargo.lock | 25 ++++++++++++++++++++ Cargo.toml | 7 ++++++ a.txt | 4 ++++ b.txt | 5 ++++ readme.md | 7 ++++++ src/difference.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 41 ++++++++++++++++++++++++++++++++ 12 files changed, 182 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/modules.xml create mode 100644 .idea/ndiff.iml create mode 100644 .idea/vcs.xml create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 a.txt create mode 100644 b.txt create mode 100644 readme.md create mode 100644 src/difference.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e627f7f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/ndiff.iml b/.idea/ndiff.iml new file mode 100644 index 0000000..cf84ae4 --- /dev/null +++ b/.idea/ndiff.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..b27437d --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,25 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "ndiff" +version = "0.1.0" +dependencies = [ + "itertools", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..c0750fc --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ndiff" +version = "0.1.0" +edition = "2021" + +[dependencies] +itertools = "0.13.0" \ No newline at end of file diff --git a/a.txt b/a.txt new file mode 100644 index 0000000..b720cf8 --- /dev/null +++ b/a.txt @@ -0,0 +1,4 @@ +ala +bala +porto +cala diff --git a/b.txt b/b.txt new file mode 100644 index 0000000..49b8563 --- /dev/null +++ b/b.txt @@ -0,0 +1,5 @@ +ala +alab +porto +cala +$$ \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..49d4b3c --- /dev/null +++ b/readme.md @@ -0,0 +1,7 @@ +# Ndiff + +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 +the [diff](https://linux.die.net/man/1/diff) command, +since it's utility is to learn Rust concepts by completing a simple project. \ No newline at end of file diff --git a/src/difference.rs b/src/difference.rs new file mode 100644 index 0000000..dd69c92 --- /dev/null +++ b/src/difference.rs @@ -0,0 +1,59 @@ +use std::fmt; +use std::fmt::Formatter; +use std::ops::Deref; + +/// A line difference is represented by the Difference struct. +#[derive(Debug)] +pub(crate) struct Difference { + line_number: i32, + missing_line_indicator: String, + left_line: String, + right_line: String, +} + +impl Difference { + pub fn new(line_number: i32, left_line: String, right_line: String) -> Difference { + Difference { + line_number, + missing_line_indicator: String::from(""), + left_line: left_line.into(), + right_line: right_line.into(), + } + } + + /// 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 + } +} + +/// Implements the display trait. +impl fmt::Display for Difference { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!( + f, + r#"Line: {}. +< {} +---- +> {} + +"#, + self.line_number, + self.left_line(), + self.right_line() + ) + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..0fc40e3 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,41 @@ +use crate::difference::Difference; +use itertools::Itertools; +use std::fs::read_to_string; + +mod difference; + +/// Gets the differences of lines that differ in the given text. +/// +/// It returns a [`Vec`] +fn get_differences(left_text: &String, right_text: &String) -> Vec { + left_text + .lines() + .map(String::from) + .zip_longest(right_text.lines().map(String::from)) + .enumerate() + .filter_map(|(line, item)| -> Option { + let left = item.clone().left().unwrap_or(String::from("")); + let right = item.right().unwrap_or(String::from("")); + + if left != right { + Some(Difference::new(line as i32 + 1, left, right)) + } else { + return None; + } + }) + .collect() +} + +fn main() { + let left_file = + read_to_string("/Users/dnutiu/RustroverProjects/ndiff/a.txt").expect("Left file not found"); + let right_file = + read_to_string("/Users/dnutiu/RustroverProjects/ndiff/b.txt").expect("Right file found"); + + let res: Vec = get_differences(&left_file, &right_file); + + for diff in res.iter() { + print!("{diff}") + } + println!("Found {} differences.", res.len()) +}