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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
rust: [stable, beta, nightly, 1.75.0]
rust: [stable, beta, nightly, 1.85.0]

steps:
- uses: actions/checkout@v6
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ repository = "https://github.com/bmwill/diffy"
readme = "README.md"
keywords = ["diff", "patch", "merge"]
categories = ["text-processing"]
rust-version = "1.75.0"
edition = "2021"
rust-version = "1.85.0"
edition = "2024"

[package.metadata.docs.rs]
# To build locally:
Expand All @@ -35,7 +35,7 @@ binary = ["dep:zlib-rs"]
color = ["dep:anstyle"]

[dependencies]
hashbrown = { version = "0.16.1", default-features = false, features = ["default-hasher"] }
hashbrown = { version = "0.17.0", default-features = false, features = ["default-hasher"] }
anstyle = { version = "1.0.13", default-features = false, optional = true }
zlib-rs = { version = "0.6.3", optional = true, default-features = false, features = ["c-allocator"] }

Expand Down
2 changes: 1 addition & 1 deletion examples/patch_formatter.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use diffy::create_patch;
use diffy::PatchFormatter;
use diffy::create_patch;

fn main() {
let original = "first line\nlast line";
Expand Down
8 changes: 3 additions & 5 deletions src/apply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ impl fmt::Display for ApplyError {
}
}

#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for ApplyError {}
impl core::error::Error for ApplyError {}

#[derive(Debug)]
enum ImageLine<'a, T: ?Sized> {
Expand Down Expand Up @@ -60,8 +58,8 @@ impl<T: ?Sized> Clone for ImageLine<'_, T> {
/// Apply a `Patch` to a base image
///
/// ```
/// use diffy::apply;
/// use diffy::Patch;
/// use diffy::apply;
///
/// let s = "\
/// --- a/ideals
Expand Down Expand Up @@ -112,8 +110,8 @@ pub fn apply(base_image: &str, patch: &Patch<'_, str>) -> Result<String, ApplyEr
/// # Examples
///
/// ```
/// use diffy::apply_bytes;
/// use diffy::Patch;
/// use diffy::apply_bytes;
///
/// let patch = Patch::from_bytes(
/// b"\
Expand Down
7 changes: 3 additions & 4 deletions src/binary/base85.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ impl fmt::Display for Base85Error {
}
}

#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for Base85Error {}
impl core::error::Error for Base85Error {}

/// Decodes a Base85 string to the provided output.
///
Expand Down Expand Up @@ -92,7 +90,8 @@ pub fn decode_into(input: &[u8], output: &mut impl Extend<u8>) -> Result<(), Bas
/// Callers encoding data where the byte count isn't a multiple of 4
/// must handle padding at a higher level.
/// For example, via a length indicator in Git binary patch format.
#[allow(dead_code)] // will be used for patch formatting
// will be used for patch formatting
#[cfg_attr(not(test), expect(dead_code))]
pub fn encode_into(input: &[u8], output: &mut impl Extend<char>) -> Result<(), Base85Error> {
if input.len() % 4 != 0 {
return Err(Base85Error::InvalidLength);
Expand Down
4 changes: 1 addition & 3 deletions src/binary/delta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,7 @@ impl fmt::Display for DeltaError {
}
}

#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for DeltaError {}
impl core::error::Error for DeltaError {}

#[cfg(test)]
mod tests {
Expand Down
12 changes: 3 additions & 9 deletions src/binary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,7 @@ impl fmt::Display for BinaryPatchParseError {
}
}

#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for BinaryPatchParseError {}
impl core::error::Error for BinaryPatchParseError {}

#[cfg(feature = "binary")]
impl From<base85::Base85Error> for BinaryPatchParseError {
Expand All @@ -320,8 +318,6 @@ impl From<BinaryPatchParseErrorKind> for BinaryPatchParseError {
#[non_exhaustive]
pub(crate) enum BinaryPatchParseErrorKind {
/// Missing or invalid "GIT binary patch" header.
// TODO: Switch to #[expect(dead_code)] when MSRV >= 1.81
#[cfg_attr(not(feature = "binary"), allow(dead_code))]
InvalidHeader,

/// First binary block (forward) not found.
Expand All @@ -331,13 +327,11 @@ pub(crate) enum BinaryPatchParseErrorKind {
MissingReverseBlock,

/// No binary data available (marker-only patch).
// TODO: Switch to #[expect(dead_code)] when MSRV >= 1.81
#[cfg_attr(not(feature = "binary"), allow(dead_code))]
#[cfg_attr(not(feature = "binary"), expect(dead_code))]
NoBinaryData,

/// Invalid line length indicator in Base85 data.
// TODO: Switch to #[expect(dead_code)] when MSRV >= 1.81
#[cfg_attr(not(feature = "binary"), allow(dead_code))]
#[cfg_attr(not(feature = "binary"), expect(dead_code))]
InvalidLineLengthIndicator,

/// Base85 decoding failed.
Expand Down
3 changes: 0 additions & 3 deletions src/diff/cleanup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use alloc::vec::Vec;

// Walks through all edits and shifts them up and then down, trying to see if they run into similar
// edits which can be merged
#[allow(clippy::needless_lifetimes)]
pub fn compact<'a, 'b, T: ?Sized + SliceLike>(diffs: &mut Vec<DiffRange<'a, 'b, T>>) {
// First attempt to compact all Deletions
let mut pointer = 0;
Expand All @@ -29,7 +28,6 @@ pub fn compact<'a, 'b, T: ?Sized + SliceLike>(diffs: &mut Vec<DiffRange<'a, 'b,
}

// Attempts to shift the Insertion or Deletion at location `pointer` as far upwards as possible.
#[allow(clippy::needless_lifetimes)]
fn shift_diff_up<'a, 'b, T: ?Sized + SliceLike>(
diffs: &mut Vec<DiffRange<'a, 'b, T>>,
mut pointer: usize,
Expand Down Expand Up @@ -131,7 +129,6 @@ fn shift_diff_up<'a, 'b, T: ?Sized + SliceLike>(
}

// Attempts to shift the Insertion or Deletion at location `pointer` as far downwards as possible.
#[allow(clippy::needless_lifetimes)]
fn shift_diff_down<'a, 'b, T: ?Sized + SliceLike>(
diffs: &mut Vec<DiffRange<'a, 'b, T>>,
mut pointer: usize,
Expand Down
6 changes: 2 additions & 4 deletions src/diff/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ mod myers;
mod tests;

// TODO determine if this should be exposed in the public API
#[allow(dead_code)]
#[derive(Debug, PartialEq, Eq)]
enum Diff<'a, T: ?Sized> {
Equal(&'a T),
Expand Down Expand Up @@ -117,7 +116,7 @@ impl DiffOptions {
/// produce a prettier diff by reducing the number of edited blocks by shifting and merging
/// edit blocks.
// TODO determine if this should be exposed in the public API
#[allow(dead_code)]
#[expect(dead_code)]
fn set_compact(&mut self, compact: bool) -> &mut Self {
self.compact = compact;
self
Expand Down Expand Up @@ -146,7 +145,6 @@ impl DiffOptions {
}

// TODO determine if this should be exposed in the public API
#[allow(dead_code)]
fn diff<'a>(&self, original: &'a str, modified: &'a str) -> Vec<Diff<'a, str>> {
let solution = myers::diff(original.as_bytes(), modified.as_bytes());

Expand Down Expand Up @@ -229,7 +227,7 @@ impl Default for DiffOptions {
}

// TODO determine if this should be exposed in the public API
#[allow(dead_code)]
#[cfg_attr(not(test), expect(dead_code))]
fn diff<'a>(original: &'a str, modified: &'a str) -> Vec<Diff<'a, str>> {
DiffOptions::default().diff(original, modified)
}
Expand Down
8 changes: 4 additions & 4 deletions src/diff/tests.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use super::*;
use crate::PatchFormatter;
use crate::apply::apply;
use crate::diff::Diff;
use crate::diff::DiffRange;
use crate::patch::Patch;
use crate::range::Range;
use crate::PatchFormatter;
use alloc::format;
use alloc::string::ToString;
use alloc::vec;
Expand Down Expand Up @@ -59,7 +59,7 @@ macro_rules! assert_diff_range {
expected, $solution,
);
};
([$($kind:ident($text:literal)),* $(,)?], $solution:ident, $msg:expr $(,)?) => {
([$($kind:ident($text:literal)),* $(,)?], $solution:ident, $msg:expr_2021 $(,)?) => {
let expected = &[$(Diff::$kind($text)),*];
assert!(
same_diffs(expected, &$solution),
Expand Down Expand Up @@ -91,7 +91,7 @@ macro_rules! assert_diff {
expected, $solution,
);
};
([$($kind:ident($text:literal)),* $(,)?], $solution:ident, $msg:expr $(,)?) => {
([$($kind:ident($text:literal)),* $(,)?], $solution:ident, $msg:expr_2021 $(,)?) => {
let expected: &[_] = &[$(Diff::$kind($text)),*];
assert_eq!(
expected,
Expand Down Expand Up @@ -328,7 +328,7 @@ fn test_compact() {
}

macro_rules! assert_patch {
($diff_options:expr, $old:ident, $new:ident, $expected:ident $(,)?) => {
($diff_options:expr_2021, $old:ident, $new:ident, $expected:ident $(,)?) => {
let patch = $diff_options.create_patch($old, $new);
let bpatch = $diff_options.create_patch_bytes($old.as_bytes(), $new.as_bytes());
let patch_str = patch.to_string();
Expand Down
12 changes: 6 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
//! This crate is `no_std` by default.
//! Enable [Cargo features] as needed:
//!
//! - `std` for writer-based formatting and `std::error::Error` impls
//! - `std` for std::io::Write-based formatting impls
//! - `color` for ANSI-colored patch formatting
//! - `binary` for applying parsed git binary patches
//!
Expand Down Expand Up @@ -112,8 +112,8 @@
//! image.
//!
//! ```
//! use diffy::apply;
//! use diffy::Patch;
//! use diffy::apply;
//!
//! let s = "\
//! --- a/skybreaker-ideals
Expand Down Expand Up @@ -323,16 +323,16 @@ pub mod patch_set;
mod range;
mod utils;

pub use apply::ApplyError;
pub use apply::apply;
pub use apply::apply_bytes;
pub use apply::ApplyError;
pub use diff::DiffOptions;
pub use diff::create_patch;
pub use diff::create_patch_bytes;
pub use diff::DiffOptions;
pub use merge::merge;
pub use merge::merge_bytes;
pub use merge::ConflictStyle;
pub use merge::MergeOptions;
pub use merge::merge;
pub use merge::merge_bytes;
pub use patch::Hunk;
pub use patch::HunkRange;
pub use patch::Line;
Expand Down
5 changes: 2 additions & 3 deletions src/merge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,10 +424,10 @@ fn merge_solutions<'ancestor, 'ours, 'theirs, T: ?Sized + SliceLike>(

solution.push(merge_range);

if ours.map_or(true, |range| range.is_empty()) {
if ours.is_none_or(|range| range.is_empty()) {
ours = our_solution.next();
}
if theirs.map_or(true, |range| range.is_empty()) {
if theirs.is_none_or(|range| range.is_empty()) {
theirs = their_solution.next();
}
}
Expand Down Expand Up @@ -524,7 +524,6 @@ fn create_merge_range<'ancestor, 'ours, 'theirs, T: ?Sized + SliceLike>(
}
}

#[allow(clippy::needless_lifetimes)]
fn cleanup_conflicts<'ancestor, 'ours, 'theirs, T: ?Sized + SliceLike + PartialEq>(
solution: &mut [MergeRange<'ancestor, 'ours, 'theirs, T>],
) {
Expand Down
10 changes: 5 additions & 5 deletions src/merge/tests.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use super::*;

macro_rules! assert_merge {
($original:ident, $ours:ident, $theirs:ident, $kind:ident($expected:expr), $msg:literal $(,)?) => {
($original:ident, $ours:ident, $theirs:ident, $kind:ident($expected:expr_2021), $msg:literal $(,)?) => {
let solution = merge($original, $ours, $theirs);

macro_rules! result {
(Ok, $s:expr) => {
(Ok, $s:expr_2021) => {
Result::<&str, &str>::Ok($s)
};
(Err, $s:expr) => {
(Err, $s:expr_2021) => {
Result::<&str, &str>::Err($s)
};
}
Expand All @@ -23,10 +23,10 @@ macro_rules! assert_merge {
merge_bytes($original.as_bytes(), $ours.as_bytes(), $theirs.as_bytes());

macro_rules! result_bytes {
(Ok, $s:expr) => {
(Ok, $s:expr_2021) => {
Result::<&[u8], &[u8]>::Ok($s.as_bytes())
};
(Err, $s:expr) => {
(Err, $s:expr_2021) => {
Result::<&[u8], &[u8]>::Err($s.as_bytes())
};
}
Expand Down
4 changes: 1 addition & 3 deletions src/patch/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ impl fmt::Display for ParsePatchError {
}
}

#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for ParsePatchError {}
impl core::error::Error for ParsePatchError {}

impl From<ParsePatchErrorKind> for ParsePatchError {
fn from(kind: ParsePatchErrorKind) -> Self {
Expand Down
8 changes: 4 additions & 4 deletions src/patch/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ use core::fmt::Result;
#[cfg(feature = "std")]
use std::io;

#[cfg(feature = "color")]
use super::style;
use super::Hunk;
use super::Line;
use super::Patch;
use super::NO_NEWLINE_AT_EOF;
use super::Patch;
#[cfg(feature = "color")]
use super::style;

/// Formats patches for display or writing into byte streams.
///
/// # Examples
///
/// ```
/// use diffy::create_patch;
/// use diffy::PatchFormatter;
/// use diffy::create_patch;
///
/// let patch = create_patch("alpha\nbeta\n", "ALPHA\nbeta\n");
/// let formatter = PatchFormatter::new().missing_newline_message(false);
Expand Down
2 changes: 1 addition & 1 deletion src/patch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl<'a> Patch<'a, str> {
///
/// let patch = Patch::from_str(s).unwrap();
/// ```
#[allow(clippy::should_implement_trait)]
#[expect(clippy::should_implement_trait)]
pub fn from_str(s: &'a str) -> Result<Patch<'a, str>, ParsePatchError> {
parse::parse(s)
}
Expand Down
Loading
Loading