initial commit
This commit is contained in:
commit
e2521179b7
12 changed files with 182 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal 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
8
.idea/modules.xml
Normal 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
11
.idea/ndiff.iml
Normal 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
6
.idea/vcs.xml
Normal 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
25
Cargo.lock
generated
Normal 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
7
Cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[package]
|
||||||
|
name = "ndiff"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
itertools = "0.13.0"
|
4
a.txt
Normal file
4
a.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
ala
|
||||||
|
bala
|
||||||
|
porto
|
||||||
|
cala
|
5
b.txt
Normal file
5
b.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
ala
|
||||||
|
alab
|
||||||
|
porto
|
||||||
|
cala
|
||||||
|
$$
|
7
readme.md
Normal file
7
readme.md
Normal 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
59
src/difference.rs
Normal 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
41
src/main.rs
Normal 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())
|
||||||
|
}
|
Loading…
Reference in a new issue