use core::fmt;
use core::ops::Range;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParsePatchError {
pub(crate) kind: ParsePatchErrorKind,
span: Option<Range<usize>>,
}
impl ParsePatchError {
pub(crate) fn new(kind: ParsePatchErrorKind, span: Range<usize>) -> Self {
Self {
kind,
span: Some(span),
}
}
}
impl fmt::Display for ParsePatchError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(span) = &self.span {
write!(
f,
"error parsing patch at byte {}: {}",
span.start, self.kind
)
} else {
write!(f, "error parsing patch: {}", self.kind)
}
}
}
impl core::error::Error for ParsePatchError {}
impl From<ParsePatchErrorKind> for ParsePatchError {
fn from(kind: ParsePatchErrorKind) -> Self {
Self { kind, span: None }
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub(crate) enum ParsePatchErrorKind {
UnexpectedEof,
MultipleOriginalHeaders,
MultipleModifiedHeaders,
InvalidFilename,
FilenameUnterminated,
InvalidCharInUnquotedFilename,
ExpectedEscapedChar,
InvalidEscapedChar,
InvalidUnescapedChar,
InvalidHunkHeader,
HunkHeaderUnterminated,
InvalidRange,
HunksOutOfOrder,
HunkMismatch,
ExpectedEndOfHunk,
TooManyDeletedLines,
TooManyInsertedLines,
UnexpectedNoNewlineMarker,
UnexpectedHunkLine,
MissingNewline,
OrphanedHunkHeader,
InvalidUtf8Path,
}
impl fmt::Display for ParsePatchErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let msg = match self {
Self::UnexpectedEof => "unexpected EOF",
Self::MultipleOriginalHeaders => "multiple '---' lines",
Self::MultipleModifiedHeaders => "multiple '+++' lines",
Self::InvalidFilename => "unable to parse filename",
Self::FilenameUnterminated => "filename unterminated",
Self::InvalidCharInUnquotedFilename => "invalid char in unquoted filename",
Self::ExpectedEscapedChar => "expected escaped character",
Self::InvalidEscapedChar => "invalid escaped character",
Self::InvalidUnescapedChar => "invalid unescaped character",
Self::InvalidHunkHeader => "unable to parse hunk header",
Self::HunkHeaderUnterminated => "hunk header unterminated",
Self::InvalidRange => "can't parse range",
Self::HunksOutOfOrder => "hunks not in order or overlap",
Self::HunkMismatch => "hunk header does not match hunk",
Self::ExpectedEndOfHunk => "expected end of hunk",
Self::TooManyDeletedLines => "expected no more deleted lines",
Self::TooManyInsertedLines => "expected no more inserted lines",
Self::UnexpectedNoNewlineMarker => "unexpected 'No newline at end of file' line",
Self::UnexpectedHunkLine => "unexpected line in hunk body",
Self::MissingNewline => "missing newline",
Self::OrphanedHunkHeader => "orphaned hunk header after trailing content",
Self::InvalidUtf8Path => "filename is not valid UTF-8",
};
write!(f, "{msg}")
}
}