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
30 changes: 30 additions & 0 deletions src/diff/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
diff::{Diff, DiffRange},
patch::Patch,
range::Range,
PatchFormatter,
};

// Helper macros are based off of the ones used in [dissimilar](https://docs.rs/dissimilar)
Expand Down Expand Up @@ -518,6 +519,35 @@ fn no_newline_at_eof() {
assert_patch!(old, new, expected);
}

#[test]
fn without_no_newline_at_eof_message() {
let old = "old line";
let new = "new line";
let expected = "\
--- original
+++ modified
@@ -1 +1 @@
-old line
+new line
";

let f = PatchFormatter::new().missing_newline_message(false);
let patch = create_patch(old, new);
let bpatch = create_patch_bytes(old.as_bytes(), new.as_bytes());
let patch_str = format!("{}", f.fmt_patch(&patch));
let mut patch_bytes = Vec::new();
f.write_patch_into(&bpatch, &mut patch_bytes).unwrap();

assert_eq!(patch_str, expected);
assert_eq!(patch_bytes, patch_str.as_bytes());
assert_eq!(patch_bytes, expected.as_bytes());
assert_eq!(apply(old, &patch).unwrap(), new);
assert_eq!(
crate::apply_bytes(old.as_bytes(), &bpatch).unwrap(),
new.as_bytes()
);
}

#[test]
fn myers_diffy_vs_git() {
let original = "\
Expand Down
23 changes: 21 additions & 2 deletions src/patch/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::{
#[derive(Debug)]
pub struct PatchFormatter {
with_color: bool,
with_missing_newline_message: bool,

context: Style,
delete: Style,
Expand All @@ -23,6 +24,7 @@ impl PatchFormatter {
pub fn new() -> Self {
Self {
with_color: false,
with_missing_newline_message: true,

context: Style::new(),
delete: Color::Red.normal(),
Expand All @@ -39,6 +41,19 @@ impl PatchFormatter {
self
}

/// Sets whether to format a patch with a "No newline at end of file" message.
///
/// Default is `true`.
///
/// Note: If this is disabled by setting to `false`, formatted patches will no longer contain
/// sufficient information to determine if a file ended with a newline character (`\n`) or not
/// and the patch will be formatted as if both the original and modified files ended with a
/// newline character (`\n`).
pub fn missing_newline_message(mut self, enable: bool) -> Self {
self.with_missing_newline_message = enable;
self
}

/// Returns a `Display` impl which can be used to print a Patch
pub fn fmt_patch<'a>(&'a self, patch: &'a Patch<'a, str>) -> impl Display + 'a {
PatchDisplay { f: self, patch }
Expand Down Expand Up @@ -238,7 +253,9 @@ impl<T: AsRef<[u8]> + ?Sized> LineDisplay<'_, T> {

if !line.ends_with(b"\n") {
writeln!(w)?;
writeln!(w, "{}", NO_NEWLINE_AT_EOF)?;
if self.f.with_missing_newline_message {
writeln!(w, "{}", NO_NEWLINE_AT_EOF)?;
}
}

Ok(())
Expand Down Expand Up @@ -269,7 +286,9 @@ impl Display for LineDisplay<'_, str> {

if !line.ends_with('\n') {
writeln!(f)?;
writeln!(f, "{}", NO_NEWLINE_AT_EOF)?;
if self.f.with_missing_newline_message {
writeln!(f, "{}", NO_NEWLINE_AT_EOF)?;
}
}

Ok(())
Expand Down
Loading