Moved code around for unified diff handling
This commit is contained in:
parent
503d912262
commit
861c53889d
10 changed files with 49 additions and 50 deletions
|
|
@ -6,7 +6,8 @@ All notable changes to similar are documented here.
|
||||||
|
|
||||||
* Add `DiffOp::apply_to_hook` to apply a captured op to a diff hook.
|
* Add `DiffOp::apply_to_hook` to apply a captured op to a diff hook.
|
||||||
* Added virtual newline handling to `iter_changes`.
|
* Added virtual newline handling to `iter_changes`.
|
||||||
* Moved unified diff support into separate module `udiff`.
|
* Made unified diff support more flexible through the introduction of
|
||||||
|
the `UnifiedDiff` type.
|
||||||
|
|
||||||
## 0.4.0
|
## 0.4.0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
//! trait bounds necessary, as well as a generic interface.
|
//! trait bounds necessary, as well as a generic interface.
|
||||||
//! * [`text`]: This extends the general diffing functionality to text (and more
|
//! * [`text`]: This extends the general diffing functionality to text (and more
|
||||||
//! specifically line) based diff operations.
|
//! specifically line) based diff operations.
|
||||||
//! * [`udiff`]: Unified diff functionality.
|
|
||||||
//!
|
//!
|
||||||
//! ## Features
|
//! ## Features
|
||||||
//!
|
//!
|
||||||
|
|
@ -33,4 +32,3 @@
|
||||||
//! If the crate is used without default features it's removed.
|
//! If the crate is used without default features it's removed.
|
||||||
pub mod algorithms;
|
pub mod algorithms;
|
||||||
pub mod text;
|
pub mod text;
|
||||||
pub mod udiff;
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
source: src/text.rs
|
|
||||||
expression: "&diff.unified_diff(3, Some((\"old\", \"new\")))"
|
|
||||||
---
|
|
||||||
--- old
|
|
||||||
+++ new
|
|
||||||
@@ -0 +2 @@
|
|
||||||
Hello World
|
|
||||||
-some stuff here
|
|
||||||
+some amazing stuff here
|
|
||||||
some more stuff here
|
|
||||||
|
|
@ -55,8 +55,10 @@ use std::borrow::Cow;
|
||||||
use std::cmp::Reverse;
|
use std::cmp::Reverse;
|
||||||
use std::collections::{BinaryHeap, HashMap};
|
use std::collections::{BinaryHeap, HashMap};
|
||||||
|
|
||||||
|
mod udiff;
|
||||||
|
pub use self::udiff::*;
|
||||||
|
|
||||||
use crate::algorithms::{capture_diff_slices, group_diff_ops, Algorithm, DiffOp, DiffTag};
|
use crate::algorithms::{capture_diff_slices, group_diff_ops, Algorithm, DiffOp, DiffTag};
|
||||||
use crate::udiff::UnifiedDiff;
|
|
||||||
|
|
||||||
/// A builder type config for more complex uses of [`TextDiff`].
|
/// A builder type config for more complex uses of [`TextDiff`].
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
source: src/text.rs
|
source: src/text/mod.rs
|
||||||
expression: "&diff.ops()"
|
expression: "&diff.ops()"
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
source: src/text.rs
|
source: src/text/mod.rs
|
||||||
expression: diff.ops()
|
expression: diff.ops()
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
source: src/text.rs
|
source: src/text/mod.rs
|
||||||
expression: "&changes"
|
expression: "&changes"
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
12
src/text/snapshots/similar__text__unified_diff.snap
Normal file
12
src/text/snapshots/similar__text__unified_diff.snap
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
source: src/text/mod.rs
|
||||||
|
expression: "&diff.unified_diff().context_radius(3).header(\"old\", \"new\").to_string()"
|
||||||
|
---
|
||||||
|
--- old
|
||||||
|
+++ new
|
||||||
|
@@ -0 +2 @@
|
||||||
|
Hello World
|
||||||
|
-some stuff here
|
||||||
|
+some amazing stuff here
|
||||||
|
some more stuff here
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
source: src/text.rs
|
source: src/text/mod.rs
|
||||||
expression: "&changes"
|
expression: "&changes"
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
//! .context_radius(10)
|
//! .context_radius(10)
|
||||||
//! .header("old_file", "new_file"));
|
//! .header("old_file", "new_file"));
|
||||||
//! ```
|
//! ```
|
||||||
#![cfg(feature = "text")]
|
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
@ -21,13 +20,12 @@ use std::ops::Range;
|
||||||
use crate::algorithms::{Algorithm, DiffOp};
|
use crate::algorithms::{Algorithm, DiffOp};
|
||||||
use crate::text::{Change, ChangeTag, TextDiff};
|
use crate::text::{Change, ChangeTag, TextDiff};
|
||||||
|
|
||||||
/// Represents a range of a unified diff hunk.
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
struct HunkRange(usize, usize);
|
struct UnifiedDiffHunkRange(usize, usize);
|
||||||
|
|
||||||
impl HunkRange {
|
impl UnifiedDiffHunkRange {
|
||||||
fn new(range: Range<usize>) -> HunkRange {
|
fn new(range: Range<usize>) -> UnifiedDiffHunkRange {
|
||||||
HunkRange(range.start, range.end)
|
UnifiedDiffHunkRange(range.start, range.end)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&self) -> usize {
|
fn start(&self) -> usize {
|
||||||
|
|
@ -39,7 +37,7 @@ impl HunkRange {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for HunkRange {
|
impl fmt::Display for UnifiedDiffHunkRange {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let mut beginning = self.start();
|
let mut beginning = self.start();
|
||||||
let len = self.end() - self.start();
|
let len = self.end() - self.start();
|
||||||
|
|
@ -55,29 +53,29 @@ impl fmt::Display for HunkRange {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Formats a unified diff hunk header for a group of diff operations.
|
/// Unified diff hunk header formatter.
|
||||||
pub struct HunkHeader {
|
pub struct UnifiedHunkHeader {
|
||||||
old_range: HunkRange,
|
old_range: UnifiedDiffHunkRange,
|
||||||
new_range: HunkRange,
|
new_range: UnifiedDiffHunkRange,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HunkHeader {
|
impl UnifiedHunkHeader {
|
||||||
/// Creates a hunk header from a (non empty) slice of diff ops.
|
/// Creates a hunk header from a (non empty) slice of diff ops.
|
||||||
pub fn new(ops: &[DiffOp]) -> HunkHeader {
|
pub fn new(ops: &[DiffOp]) -> UnifiedHunkHeader {
|
||||||
HunkHeader {
|
UnifiedHunkHeader {
|
||||||
old_range: HunkRange::new(ops[0].old_range()),
|
old_range: UnifiedDiffHunkRange::new(ops[0].old_range()),
|
||||||
new_range: HunkRange::new(ops[ops.len() - 1].new_range()),
|
new_range: UnifiedDiffHunkRange::new(ops[ops.len() - 1].new_range()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for HunkHeader {
|
impl fmt::Display for UnifiedHunkHeader {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "@@ -{} +{} @@", &self.old_range, &self.new_range)
|
write!(f, "@@ -{} +{} @@", &self.old_range, &self.new_range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A unified diff formatter.
|
/// Unified diff formatter.
|
||||||
///
|
///
|
||||||
/// The `Display` implementation renders a unified diff.
|
/// The `Display` implementation renders a unified diff.
|
||||||
pub struct UnifiedDiff<'diff, 'old, 'new, 'bufs> {
|
pub struct UnifiedDiff<'diff, 'old, 'new, 'bufs> {
|
||||||
|
|
@ -109,13 +107,13 @@ impl<'diff, 'old, 'new, 'bufs> UnifiedDiff<'diff, 'old, 'new, 'bufs> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterates over all hunks as configured.
|
/// Iterates over all hunks as configured.
|
||||||
pub fn iter_hunks(&self) -> impl Iterator<Item = Hunk<'diff, 'old, 'new, 'bufs>> {
|
pub fn iter_hunks(&self) -> impl Iterator<Item = UnifiedDiffHunk<'diff, 'old, 'new, 'bufs>> {
|
||||||
let diff = self.diff;
|
let diff = self.diff;
|
||||||
self.diff
|
self.diff
|
||||||
.grouped_ops(self.context_radius)
|
.grouped_ops(self.context_radius)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|ops| !ops.is_empty())
|
.filter(|ops| !ops.is_empty())
|
||||||
.map(move |ops| Hunk::new(ops, diff))
|
.map(move |ops| UnifiedDiffHunk::new(ops, diff))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn header_opt(&mut self, header: Option<(&str, &str)>) -> &mut Self {
|
fn header_opt(&mut self, header: Option<(&str, &str)>) -> &mut Self {
|
||||||
|
|
@ -126,27 +124,26 @@ impl<'diff, 'old, 'new, 'bufs> UnifiedDiff<'diff, 'old, 'new, 'bufs> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents a single hunk in a unified diff.
|
/// Unified diff hunk formatter.
|
||||||
///
|
///
|
||||||
/// When formatted with `Display` this renders out a single unified diff's
|
/// The `Display` this renders out a single unified diff's hunk.
|
||||||
/// hunk.
|
pub struct UnifiedDiffHunk<'diff, 'old, 'new, 'bufs> {
|
||||||
pub struct Hunk<'diff, 'old, 'new, 'bufs> {
|
|
||||||
diff: &'diff TextDiff<'old, 'new, 'bufs>,
|
diff: &'diff TextDiff<'old, 'new, 'bufs>,
|
||||||
ops: Vec<DiffOp>,
|
ops: Vec<DiffOp>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'diff, 'old, 'new, 'bufs> Hunk<'diff, 'old, 'new, 'bufs> {
|
impl<'diff, 'old, 'new, 'bufs> UnifiedDiffHunk<'diff, 'old, 'new, 'bufs> {
|
||||||
/// Creates a new hunk for some operations.
|
/// Creates a new hunk for some operations.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
ops: Vec<DiffOp>,
|
ops: Vec<DiffOp>,
|
||||||
diff: &'diff TextDiff<'old, 'new, 'bufs>,
|
diff: &'diff TextDiff<'old, 'new, 'bufs>,
|
||||||
) -> Hunk<'diff, 'old, 'new, 'bufs> {
|
) -> UnifiedDiffHunk<'diff, 'old, 'new, 'bufs> {
|
||||||
Hunk { diff, ops }
|
UnifiedDiffHunk { diff, ops }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the header for the hunk.
|
/// Returns the header for the hunk.
|
||||||
pub fn header(&self) -> HunkHeader {
|
pub fn header(&self) -> UnifiedHunkHeader {
|
||||||
HunkHeader::new(&self.ops)
|
UnifiedHunkHeader::new(&self.ops)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all operations in the hunk.
|
/// Returns all operations in the hunk.
|
||||||
|
|
@ -155,7 +152,7 @@ impl<'diff, 'old, 'new, 'bufs> Hunk<'diff, 'old, 'new, 'bufs> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterates over all changes in a hunk.
|
/// Iterates over all changes in a hunk.
|
||||||
pub fn iter_changes(&self) -> impl Iterator<Item = Change<'_>> {
|
pub fn iter_changes(&self) -> impl Iterator<Item = Change<'_>> + '_ {
|
||||||
// unclear why this needs Box::new here. It seems to infer some really
|
// unclear why this needs Box::new here. It seems to infer some really
|
||||||
// odd lifetimes I can't figure out how to work with.
|
// odd lifetimes I can't figure out how to work with.
|
||||||
(Box::new(
|
(Box::new(
|
||||||
|
|
@ -166,7 +163,7 @@ impl<'diff, 'old, 'new, 'bufs> Hunk<'diff, 'old, 'new, 'bufs> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'diff, 'old, 'new, 'bufs> fmt::Display for Hunk<'diff, 'old, 'new, 'bufs> {
|
impl<'diff, 'old, 'new, 'bufs> fmt::Display for UnifiedDiffHunk<'diff, 'old, 'new, 'bufs> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let nl = if self.diff.newline_terminated() {
|
let nl = if self.diff.newline_terminated() {
|
||||||
""
|
""
|
||||||
Loading…
Add table
Add a link
Reference in a new issue