Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions text/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ fn check_difference(args: Args) -> io::Result<DiffExitStatus> {
let path2_is_file = fs::metadata(&path2)?.is_file();

if path1_is_file && path2_is_file {
return FileDiff::file_diff(path1, path2, &format_options, None);
FileDiff::file_diff(path1, path2, &format_options, None)
} else if !path1_is_file && !path2_is_file {
return DirDiff::dir_diff(path1, path2, &format_options, args.recurse);
DirDiff::dir_diff(path1, path2, &format_options, args.recurse)
} else {
return FileDiff::file_dir_diff(path1, path2, &format_options);
FileDiff::file_dir_diff(path1, path2, &format_options)
}
}

Expand Down
53 changes: 0 additions & 53 deletions text/diff_util/change.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@ impl ChangeData {
pub fn new(ln1: usize, ln2: usize) -> Self {
Self { ln1, ln2 }
}

pub fn ln1(&self) -> usize {
self.ln1
}

pub fn ln2(&self) -> usize {
self.ln2
}
}

#[derive(Clone, Copy, Debug, Default, Hash)]
Expand All @@ -29,38 +21,6 @@ pub enum Change {
}

impl Change {
pub fn is_none(&self) -> bool {
*self == Change::None
}

pub fn is_unchanged(&self) -> bool {
*self == Change::Unchanged(Default::default())
}

pub fn is_insert(&self) -> bool {
*self == Change::Insert(Default::default())
}

pub fn is_delete(&self) -> bool {
*self == Change::Delete(Default::default())
}

pub fn is_substitute(&self) -> bool {
*self == Change::Substitute(Default::default())
}

/// returns (ln1,ln2)
/// panics if self is None
pub fn get_lns(&self) -> (usize, usize) {
match self {
Change::None => Default::default(),
Change::Unchanged(data) => (data.ln1, data.ln2),
Change::Insert(data) => (data.ln1, data.ln2),
Change::Delete(data) => (data.ln1, data.ln2),
Change::Substitute(data) => (data.ln1, data.ln2),
}
}

pub fn get_ln1(&self) -> usize {
match self {
Change::None => panic!("Change::None is not allowed in hunk."),
Expand All @@ -81,16 +41,3 @@ impl Change {
}
}
}

impl PartialEq for Change {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::None, Self::None) => true,
(Self::Unchanged(_), Self::Unchanged(_)) => true,
(Self::Insert(_), Self::Insert(_)) => true,
(Self::Delete(_), Self::Delete(_)) => true,
(Self::Substitute(_), Self::Substitute(_)) => true,
_ => false,
}
}
}
4 changes: 2 additions & 2 deletions text/diff_util/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
pub const EXIT_STATUS_NO_DIFFERENCE: u8 = 0;
pub const EXIT_STATUS_DIFFERENCE: u8 = 1;
pub const EXIT_STATUS_TROUBLE: u8 = 2;
pub const NO_NEW_LINE_AT_END_OF_FILE: &'static str = "\\ No newline at end of file";
pub const COULD_NOT_UNWRAP_FILENAME: &'static str = "Could not unwrap filename!";
pub const NO_NEW_LINE_AT_END_OF_FILE: &str = "\\ No newline at end of file";
pub const COULD_NOT_UNWRAP_FILENAME: &str = "Could not unwrap filename!";
pub const UTF8_NOT_ALLOWED_BYTES: [u8; 26] = [
0, 1, 2, 3, 4, 5, 6, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, 29, 30, 31,
127,
Expand Down
11 changes: 5 additions & 6 deletions text/diff_util/dir_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl<'a> DirDiff<'a> {
let mut dir2: DirData = DirData::load(path2)?;

let mut dir_diff = DirDiff::new(&mut dir1, &mut dir2, format_options, recursive);
return dir_diff.analyze();
dir_diff.analyze()
}

fn analyze(&mut self) -> io::Result<DiffExitStatus> {
Expand All @@ -48,16 +48,15 @@ impl<'a> DirDiff<'a> {
let is_file = dir_data
.files()
.get_key_value(file_name)
.expect(
format!(
.unwrap_or_else(|| {
panic!(
"Could not find file in {}",
dir_data
.path()
.to_str()
.unwrap_or(COULD_NOT_UNWRAP_FILENAME)
)
.as_str(),
)
})
.1
.file_type()?
.is_file();
Expand Down Expand Up @@ -217,6 +216,6 @@ impl<'a> DirDiff<'a> {
}
}

return Ok(exit_status);
Ok(exit_status)
}
}
127 changes: 58 additions & 69 deletions text/diff_util/file_data.rs
Original file line number Diff line number Diff line change
@@ -1,72 +1,42 @@
use std::{
fs::File,
io::{self, BufReader, Read},
path::PathBuf,
time::SystemTime,
};
use std::{fs::File, io, mem::take, path::PathBuf, str::from_utf8, time::SystemTime};

use super::{change::Change, constants::COULD_NOT_UNWRAP_FILENAME};
use super::constants::COULD_NOT_UNWRAP_FILENAME;

pub struct FileData {
#[derive(Debug)]
pub struct FileData<'a> {
path: PathBuf,
lines: Vec<String>,
changes: Vec<Change>,
lines: Vec<&'a str>,
modified: SystemTime,
ends_with_newline: bool,
}

impl FileData {
impl<'a> FileData<'a> {
pub fn ends_with_newline(&self) -> bool {
self.ends_with_newline
}

pub fn get_file(path: PathBuf) -> io::Result<Self> {
let file = File::open(path.clone())?;
pub fn get_file(
path: PathBuf,
lines: Vec<&'a str>,
ends_with_newline: bool,
) -> io::Result<Self> {
let file = File::open(&path)?;
let modified = file.metadata()?.modified()?;
let mut buf_reader = BufReader::new(file);
let mut content = String::new();
buf_reader.read_to_string(&mut content)?;

let mut lines = content
.lines()
.map(|line| line.to_string())
.collect::<Vec<String>>();

let ends_with_newline = content.ends_with("\n");

if ends_with_newline {
lines.push(String::from(""));
}

let changes = vec![Change::None; lines.len()];

let result = Self {
Ok(Self {
path,
lines,
changes,
modified,
ends_with_newline,
};

Ok(result)
})
}

pub fn get_context_identifier(&self, change_index: usize) -> &str {
match self.changes[change_index] {
Change::None => " ",
Change::Unchanged(_) => " ",
Change::Insert(_) => "+",
Change::Delete(_) => "-",
Change::Substitute(_) => "!",
}
}

pub fn lines(&self) -> &Vec<String> {
pub fn lines(&self) -> &Vec<&str> {
&self.lines
}

pub fn line(&self, index: usize) -> &String {
&self.lines[index]
pub fn line(&self, index: usize) -> &str {
self.lines[index]
}

pub fn modified(&self) -> SystemTime {
Expand All @@ -80,35 +50,54 @@ impl FileData {
}
}

return COULD_NOT_UNWRAP_FILENAME;
COULD_NOT_UNWRAP_FILENAME
}

pub fn set_change(&mut self, change: Change, index: usize) {
self.changes[index] = change;
pub fn path(&self) -> &str {
self.path.to_str().unwrap_or(COULD_NOT_UNWRAP_FILENAME)
}
}

pub fn expected_changed_in_range(
&self,
start: usize,
end: usize,
expected_changes: &Vec<fn(&Change) -> bool>,
) -> bool {
for i in start..=end {
for expected_change in expected_changes {
if expected_change(&self.changes[i]) {
return true;
}
}
}
pub struct LineReader<'a> {
content: &'a [u8],
ends_with_newline: bool,
}

return false;
impl<'a> LineReader<'a> {
pub fn new(content: &'a [u8]) -> Self {
let ends_with_newline = content.last() == Some(&b'\n');
Self {
content,
ends_with_newline,
}
}

pub fn change(&self, index: usize) -> &Change {
&self.changes[index]
pub fn ends_with_newline(&self) -> bool {
self.ends_with_newline
}
}

pub fn path(&self) -> &str {
self.path.to_str().unwrap_or(COULD_NOT_UNWRAP_FILENAME)
impl<'a> Iterator for LineReader<'a> {
type Item = &'a str;

fn next(&mut self) -> Option<Self::Item> {
let mut carriage = false;
let mut iter = self.content.iter().enumerate();
let mut line_len = loop {
match iter.next() {
Some((i, b'\n')) => break i + 1,
None => {
return (!self.content.is_empty()).then(|| {
from_utf8(take(&mut self.content)).expect("Failed to convert to str")
});
}
Some((_, &it)) => carriage = it == b'\r',
}
};
let (line, rest) = self.content.split_at(line_len);
if carriage {
line_len -= 1;
}
self.content = rest;
Some(from_utf8(&line[..line_len - 1]).expect("Failed to convert to str"))
}
}
Loading