From 6f6381d06e58dddd39b5d8ef713d89c14cf30c7b Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Tue, 9 Jul 2024 20:54:15 +0900 Subject: [PATCH] diff: leverage BStr for better debug printing --- lib/src/diff.rs | 42 +++++++++++------------------------------- lib/src/files.rs | 4 ++-- 2 files changed, 13 insertions(+), 33 deletions(-) diff --git a/lib/src/diff.rs b/lib/src/diff.rs index 200966e3f7..16c073d2e7 100644 --- a/lib/src/diff.rs +++ b/lib/src/diff.rs @@ -16,10 +16,10 @@ use std::cmp::{max, min, Ordering}; use std::collections::{BTreeMap, HashMap}; -use std::fmt::{Debug, Formatter}; use std::ops::Range; use std::{iter, slice}; +use bstr::BStr; use itertools::Itertools; pub fn find_line_ranges(text: &[u8]) -> Vec> { @@ -354,8 +354,8 @@ impl Ord for UnchangedRange { /// of them. #[derive(Clone, Debug)] pub struct Diff<'input> { - base_input: &'input [u8], - other_inputs: Vec<&'input [u8]>, + base_input: &'input BStr, + other_inputs: Vec<&'input BStr>, // The key is a range in the base input. The value is the start of each non-base region // relative to the base region's start. By making them relative, they don't need to change // when the base range changes. @@ -412,7 +412,7 @@ impl<'input> Diff<'input> { inputs: impl IntoIterator, tokenizer: impl Fn(&[u8]) -> Vec>, ) -> Self { - let mut inputs = inputs.into_iter().map(AsRef::as_ref); + let mut inputs = inputs.into_iter().map(BStr::new); let base_input = inputs.next().expect("inputs must not be empty"); let other_inputs = inputs.collect_vec(); // First tokenize each input @@ -430,8 +430,8 @@ impl<'input> Diff<'input> { } fn with_inputs_and_token_ranges( - base_input: &'input [u8], - other_inputs: Vec<&'input [u8]>, + base_input: &'input BStr, + other_inputs: Vec<&'input BStr>, base_token_ranges: &[Range], other_token_ranges: &[Vec>], ) -> Self { @@ -587,41 +587,21 @@ impl<'input> Diff<'input> { } } -#[derive(PartialEq, Eq, Clone)] +#[derive(PartialEq, Eq, Clone, Debug)] pub enum DiffHunk<'input> { - Matching(&'input [u8]), - Different(Vec<&'input [u8]>), + Matching(&'input BStr), + Different(Vec<&'input BStr>), } impl<'input> DiffHunk<'input> { pub fn matching + ?Sized>(content: &'input T) -> Self { - DiffHunk::Matching(content.as_ref()) + DiffHunk::Matching(BStr::new(content)) } pub fn different + ?Sized + 'input>( contents: impl IntoIterator, ) -> Self { - DiffHunk::Different(contents.into_iter().map(AsRef::as_ref).collect()) - } -} - -impl Debug for DiffHunk<'_> { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { - match self { - DiffHunk::Matching(slice) => f - .debug_tuple("DiffHunk::Matching") - .field(&String::from_utf8_lossy(slice)) - .finish(), - DiffHunk::Different(slices) => f - .debug_tuple("DiffHunk::Different") - .field( - &slices - .iter() - .map(|slice| String::from_utf8_lossy(slice)) - .collect_vec(), - ) - .finish(), - } + DiffHunk::Different(contents.into_iter().map(BStr::new).collect()) } } diff --git a/lib/src/files.rs b/lib/src/files.rs index 3bd658b7b7..588337bb21 100644 --- a/lib/src/files.rs +++ b/lib/src/files.rs @@ -169,11 +169,11 @@ pub fn merge(slices: &Merge<&[u8]>) -> MergeResult { for diff_hunk in diff.hunks() { match diff_hunk { DiffHunk::Matching(content) => { - resolved_hunk.0.extend(content); + resolved_hunk.0.extend_from_slice(content); } DiffHunk::Different(parts) => { if let Some(resolved) = trivial_merge(&parts[..num_diffs], &parts[num_diffs..]) { - resolved_hunk.0.extend(*resolved); + resolved_hunk.0.extend_from_slice(resolved); } else { if !resolved_hunk.0.is_empty() { merge_hunks.push(Merge::resolved(resolved_hunk));