Skip to content

Commit 4553985

Browse files
committed
base-fix
1 parent 833f7cd commit 4553985

File tree

1 file changed

+33
-36
lines changed

1 file changed

+33
-36
lines changed

src/sdiff.rs

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{
33
env::ArgsOs,
44
ffi::OsString,
55
fs,
6-
io::{stdin, Read, Write},
6+
io::{self, stdin, Read, StdoutLock, Write},
77
iter::Peekable,
88
process::ExitCode,
99
vec,
@@ -45,59 +45,56 @@ pub fn main(opts: Peekable<ArgsOs>) -> ExitCode {
4545
// first we need to get the properly files
4646
let file1 = read_file_contents(&params.file1);
4747
let file2 = read_file_contents(&params.file2);
48-
49-
// now we get the lines from the files as bytes, cuz the sdiff
48+
49+
// now we get the lines from the files as bytes, cuz the sdiff
5050
// must be compatible with ut8, ascii etc.
5151
let mut lines_left: Vec<&[u8]> = file1.split(|&c| c == b'\n').collect();
52-
let mut lines_rght: Vec<&[u8]> = file2.split(|&c| c == b'\n').collect();
52+
let mut lines_right: Vec<&[u8]> = file2.split(|&c| c == b'\n').collect();
5353

54-
// for some reason, the original file appends a empty line at
54+
// for some reason, the original file appends a empty line at
5555
// the end of file. I did not search for it, but my guess is
5656
// that this is EOL or an zeroed terminated file. Just remove it
5757
if lines_left.last() == Some(&&b""[..]) {
5858
lines_left.pop();
5959
}
6060

61-
if lines_rght.last() == Some(&&b""[..]) {
62-
lines_rght.pop();
61+
if lines_right.last() == Some(&&b""[..]) {
62+
lines_right.pop();
6363
}
6464

65-
let mut output: Vec<u8> = Vec::new();
6665
let width = 60;
67-
let max_lines = lines_left.len().max(lines_rght.len());
68-
69-
// ok, now we start running over the lines and get the lines right
70-
// and left file
71-
for i in 0..max_lines {
72-
// now we convert the bytes to utf8. May the file is encoded with invalid chars,
73-
// so it can result in a line with �.
74-
let left = lines_left.get(i).map(|l| String::from_utf8_lossy(l));
75-
let right = lines_rght.get(i).map(|r| String::from_utf8_lossy(r));
76-
77-
match (left, right) {
78-
(Some(l), Some(r)) if l == r => {
79-
// this is nice, cuz if the line is empty we stiill can print it, cause it equal : )
80-
writeln!(output, "{:<width$} {}", l, r, width = width).unwrap();
81-
}
82-
(Some(l), Some(r)) => {
83-
// if both lines are present but not equal, they are different, just print with |
84-
writeln!(output, "{:<width$} | {}", l, r, width = width).unwrap();
66+
let max_lines = lines_left.len().max(lines_right.len());
67+
68+
fn write_line(
69+
out: &mut StdoutLock,
70+
left: &[u8],
71+
right: &[u8],
72+
middle: &[u8],
73+
width: usize,
74+
) -> io::Result<()> {
75+
let count = out.write(left.get(..width).unwrap_or(left))?;
76+
write!(out, "{}", " ".repeat(width - count))?;
77+
out.write(middle)?;
78+
out.write(right.get(..width).unwrap_or(right))?;
79+
Ok(())
80+
}
81+
82+
let mut out = io::stdout().lock();
83+
for result in diff::slice(&lines_left, &lines_right) {
84+
match result {
85+
diff::Result::Left(str) => {
86+
write_line(&mut out, str, &[], b" < ", width).unwrap();
8587
}
86-
(Some(l), None) => {
87-
// we have only left val, so print it with <
88-
writeln!(output, "{:<width$} <", l, width = width).unwrap();
88+
diff::Result::Right(str) => {
89+
write_line(&mut out, &[], &str, b" > ", width).unwrap();
8990
}
90-
(None, Some(r)) => {
91-
// we have only the ...
92-
writeln!(output, "{:<width$} > {}", "", r, width = width).unwrap();
91+
diff::Result::Both(str_l, str_r) => {
92+
write_line(&mut out, str_l, str_r, b" ", width).unwrap();
9393
}
94-
_ => {}
9594
}
95+
writeln!(&mut out).unwrap();
9696
}
9797

98-
// now print the line at stdout
99-
println!("{}", String::from_utf8(output).unwrap());
100-
10198
ExitCode::SUCCESS
10299
}
103100

0 commit comments

Comments
 (0)