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 patchparser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub mod format_binary;
pub mod from_lines;
pub mod line;
pub mod patch;
pub mod re;
pub mod reborrow_in;
pub mod regex_utils;
pub mod utils;
pub mod write_to;
49 changes: 26 additions & 23 deletions patchparser/src/patch/change.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl<'a, 'h> Change<'a, 'h> {
'a: 'b,
'h: 'b,
{
let mut lines = bc::Vec::new_in(bump);
let mut remaining_lines = bc::Vec::new_in(bump);

let Self {
orig_start,
Expand All @@ -44,31 +44,34 @@ impl<'a, 'h> Change<'a, 'h> {
post,
} = self;

// Does the header need to be adapted to the following
// patterns? As discovered for `split_hunk` -- cj: Let's just
// always print the multi-line range format, it should always
// work.
// @@ -0,0 +1,2 @@
// @@ -42 42 @@
// @@ -42 +1,2 @@
// @@ -0,0 +1 @@
let mut content = BString::new_in(bump);
content.extend_from_slice(
format!(
"@@ -{},{} +{},{} ",
orig_start, orig_len, patched_start, patched_len
)
.as_bytes(),
);
content.extend_from_slice(head_post);
lines.push(Line::from_generated_content(content.into_bump_slice()));
let head_line = {
// Does the header need to be adapted to the following
// patterns? As discovered for `split_hunk` -- cj: Let's just
// always print the multi-line range format, it should always
// work.
// @@ -0,0 +1,2 @@
// @@ -42 42 @@
// @@ -42 +1,2 @@
// @@ -0,0 +1 @@
let mut content = BString::new_in(bump);
content.extend_from_slice(
format!(
"@@ -{},{} +{},{} ",
orig_start, orig_len, patched_start, patched_len
)
.as_bytes(),
);
content.extend_from_slice(head_post);
Line::from_generated_content(content.into_bump_slice())
};

lines.extend_from_slice(pre);
lines.extend_from_slice(group);
lines.extend_from_slice(post);
remaining_lines.extend_from_slice(pre);
remaining_lines.extend_from_slice(group);
remaining_lines.extend_from_slice(post);

Hunk {
lines: BumpaloCow::Owned(lines),
head_line,
remaining_lines: BumpaloCow::Owned(remaining_lines),
}
}
}
Expand Down
99 changes: 99 additions & 0 deletions patchparser/src/patch/change_line.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use anyhow::{anyhow, Result};

use crate::line::Line;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum ChangeLineKind {
/// ' '
Context,
/// '+'
Plus,
/// '-'
Minus,
/// "\ No newline at end of file"
Backslash,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum ChangeTerminator {
// "diff "
Diff,
// "@@ "
Hunk,
}

#[derive(Debug)]
pub(crate) enum ChangeLineReport {
Kind(ChangeLineKind),
Terminator(ChangeTerminator),
InvalidSyntax(anyhow::Error),
}

impl From<Line<'_>> for ChangeLineReport {
fn from(line: Line) -> Self {
use ChangeLineKind::*;
use ChangeLineReport::*;
use ChangeTerminator::*;
match line.first() {
Some(c) => match *c {
b' ' => Kind(Context),
b'+' => Kind(Plus),
b'-' => Kind(Minus),
b'\\' => Kind(Backslash),
_ => {
if line.starts_with(b"@@ ") {
Terminator(Hunk)
} else if line.starts_with(b"diff ") {
Terminator(Diff)
} else {
InvalidSyntax(anyhow!(
"invalid syntax in change on line {line}: unknown line start"
))
}
}
},
None => InvalidSyntax(anyhow!(
"invalid syntax in change on line {line}: empty line"
)),
}
}
}

impl ChangeLineReport {
/// Returns the type expected by `try_take_while` for predicates
pub(crate) fn matches_kinds(self, kinds: &[ChangeLineKind]) -> Result<(), ChangeLineReport> {
match self {
ChangeLineReport::Kind(change_line_kind) => {
if kinds.contains(&change_line_kind) {
Ok(())
} else {
Err(self)
}
}
_ => Err(self),
}
}

pub(crate) fn kind_or_terminator(self) -> Result<ChangeLineReport> {
match self {
ChangeLineReport::InvalidSyntax(error) => Err(error),
t => Ok(t),
}
}
}

pub trait SeparateErrors: Sized {
type Error;
fn separate_errors(self) -> Result<Self, Self::Error>;
}

impl SeparateErrors for Option<ChangeLineReport> {
type Error = anyhow::Error;

fn separate_errors(self) -> Result<Self, Self::Error> {
match self {
Some(report) => Ok(Some(report.kind_or_terminator()?)),
None => Ok(None),
}
}
}
3 changes: 2 additions & 1 deletion patchparser/src/patch/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ fn gather_hunks<'s>(lines: &'s [Line<'s>], bump: &'s Bump) -> bc::Vec<'s, Hunk<'
lines,
|line| line.starts_with(b"@@ "),
|group| Hunk {
lines: BumpaloCow::Borrowed(group),
head_line: group[0],
remaining_lines: BumpaloCow::Borrowed(&group[1..]),
},
bump,
)
Expand Down
Loading
Loading