initial commit

This commit is contained in:
Denis-Cosmin NUTIU 2024-10-24 17:20:52 +03:00
commit e2521179b7
12 changed files with 182 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

8
.idea/.gitignore vendored Normal file
View file

@ -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

8
.idea/modules.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ndiff.iml" filepath="$PROJECT_DIR$/.idea/ndiff.iml" />
</modules>
</component>
</project>

11
.idea/ndiff.iml Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

25
Cargo.lock generated Normal file
View file

@ -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",
]

7
Cargo.toml Normal file
View file

@ -0,0 +1,7 @@
[package]
name = "ndiff"
version = "0.1.0"
edition = "2021"
[dependencies]
itertools = "0.13.0"

4
a.txt Normal file
View file

@ -0,0 +1,4 @@
ala
bala
porto
cala

5
b.txt Normal file
View file

@ -0,0 +1,5 @@
ala
alab
porto
cala
$$

7
readme.md Normal file
View file

@ -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.

59
src/difference.rs Normal file
View file

@ -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("<missing line>"),
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()
)
}
}

41
src/main.rs Normal file
View file

@ -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<Difference>`]
fn get_differences(left_text: &String, right_text: &String) -> Vec<Difference> {
left_text
.lines()
.map(String::from)
.zip_longest(right_text.lines().map(String::from))
.enumerate()
.filter_map(|(line, item)| -> Option<Difference> {
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<Difference> = get_differences(&left_file, &right_file);
for diff in res.iter() {
print!("{diff}")
}
println!("Found {} differences.", res.len())
}