Browse Source

An even better name for decode errors

pull/80/head
Sebastian Thiel 4 weeks ago
parent
commit
f270850ff9
No known key found for this signature in database GPG Key ID: 9CB5EE7895E8268B
  1. 5
      git-object/src/commit.rs
  2. 14
      git-object/src/immutable/commit.rs
  3. 80
      git-object/src/immutable/mod.rs
  4. 69
      git-object/src/immutable/object.rs
  5. 9
      git-object/src/immutable/parse.rs
  6. 9
      git-object/src/immutable/tag.rs
  7. 5
      git-object/src/immutable/tree.rs
  8. 4
      git-odb/src/borrowed.rs
  9. 8
      git-odb/src/pack/index/verify.rs
  10. 9
      git-odb/src/traverse.rs

5
git-object/src/commit.rs

@ -1,6 +1,7 @@
use crate::immutable;
use bstr::{BStr, ByteSlice};
use crate::immutable;
/// An iterator over extra headers in [owned][crate::mutable::Commit] and [borrowed][immutable::Commit] commits.
pub struct ExtraHeaders<I> {
inner: I,
@ -29,7 +30,7 @@ where
///
/// A merge tag is a tag object embedded within the respective header field of a commit, making
/// it a child object of sorts.
pub fn mergetags(self) -> impl Iterator<Item = Result<immutable::Tag<'a>, immutable::decode::Error>> {
pub fn mergetags(self) -> impl Iterator<Item = Result<immutable::Tag<'a>, immutable::object::decode::Error>> {
self.find_all("mergetag").map(|b| immutable::Tag::from_bytes(b))
}

14
git-object/src/immutable/commit.rs

@ -1,8 +1,5 @@
use crate::{
commit,
immutable::{decode, parse, parse::NL, Signature},
BStr, ByteSlice,
};
use std::borrow::Cow;
use nom::{
branch::alt,
bytes::{complete::is_not, complete::tag},
@ -11,7 +8,12 @@ use nom::{
IResult,
};
use smallvec::SmallVec;
use std::borrow::Cow;
use crate::{
commit,
immutable::{object::decode, parse, parse::NL, Signature},
BStr, ByteSlice,
};
/// A git commit parsed using [`from_bytes()`][Commit::from_bytes()].
///

80
git-object/src/immutable/mod.rs

@ -3,83 +3,17 @@
//! Immutable objects are expected to be deserialized from bytes that acts as backing store, and they
//! cannot be mutated or serialized. Instead, one will [convert][Object::into_mutable()] them into their [`mutable`][crate::mutable] counterparts
//! which support mutation and serialization.
mod commit;
pub use blob::Blob;
pub use commit::Commit;
mod tag;
pub use object::{Object, Signature};
pub use tag::Tag;
///
pub mod tree;
pub use tree::Tree;
mod blob;
pub use blob::Blob;
mod object;
pub use object::{Object, Signature};
mod commit;
///
pub mod object;
mod parse;
mod tag;
///
pub mod decode {
use nom::error::ParseError;
use quick_error::quick_error;
quick_error! {
/// An error returned by various [`Commit`][crate::immutable::Commit] and [`Signature`][crate::immutable::Signature] methods.
#[derive(Debug)]
#[allow(missing_docs)]
pub enum Error {
ParseIntegerError(msg: &'static str, number: crate::BString, err: btoi::ParseIntegerError) {
display("{}: {:?}", msg, number)
source(err)
}
Nom(err_msg: String) {
display("{}", err_msg)
}
NomDetail(input: crate::BString, msg: &'static str) {
display("{}: '{}' could not be parsed", msg, input)
}
ParseKindError(err: crate::types::Error) {
display("{}", err)
source(err)
}
ObjectKind(err: crate::Error) {
from()
source(err)
}
}
}
impl Error {
fn set_parse_context(mut self, ctx: &'static str) -> Self {
if let Error::NomDetail(_, ref mut message) = self {
*message = ctx
}
self
}
pub(crate) fn context(msg: &'static str) -> impl Fn(nom::Err<Self>) -> nom::Err<Self> {
move |e: nom::Err<Self>| e.map(|e| e.set_parse_context(msg))
}
}
impl ParseError<&[u8]> for Error {
fn from_error_kind(input: &[u8], _kind: nom::error::ErrorKind) -> Self {
Error::NomDetail(input.into(), "parse error")
}
fn append(_: &[u8], _: nom::error::ErrorKind, other: Self) -> Self {
other
}
}
impl From<nom::Err<Error>> for Error {
fn from(e: nom::Err<Error>) -> Self {
match e {
nom::Err::Error(err) | nom::Err::Failure(err) => Error::Nom(err.to_string()),
nom::Err::Incomplete(_) => unreachable!("we do not implement streaming parsers"),
}
}
}
}
pub mod tree;

69
git-object/src/immutable/object.rs

@ -2,7 +2,7 @@ use bstr::BStr;
use crate::{
immutable,
immutable::{decode, parse, Blob, Commit, Tag, Tree},
immutable::{parse, Blob, Commit, Tag, Tree},
Kind, Time,
};
@ -108,9 +108,10 @@ impl<'a> Object<'a> {
}
mod convert {
use crate::immutable::{Blob, Commit, Object, Tag, Tree};
use std::convert::TryFrom;
use crate::immutable::{Blob, Commit, Object, Tag, Tree};
impl<'a> From<Tag<'a>> for Object<'a> {
fn from(v: Tag<'a>) -> Self {
Object::Tag(v)
@ -179,3 +180,67 @@ mod convert {
}
}
}
///
pub mod decode {
use nom::error::ParseError;
use quick_error::quick_error;
quick_error! {
/// An error returned by various [`Commit`][crate::immutable::Commit] and [`Signature`][crate::immutable::Signature] methods.
#[derive(Debug)]
#[allow(missing_docs)]
pub enum Error {
ParseIntegerError(msg: &'static str, number: crate::BString, err: btoi::ParseIntegerError) {
display("{}: {:?}", msg, number)
source(err)
}
Nom(err_msg: String) {
display("{}", err_msg)
}
NomDetail(input: crate::BString, msg: &'static str) {
display("{}: '{}' could not be parsed", msg, input)
}
ParseKindError(err: crate::types::Error) {
display("{}", err)
source(err)
}
ObjectKind(err: crate::Error) {
from()
source(err)
}
}
}
impl Error {
fn set_parse_context(mut self, ctx: &'static str) -> Self {
if let Error::NomDetail(_, ref mut message) = self {
*message = ctx
}
self
}
pub(crate) fn context(msg: &'static str) -> impl Fn(nom::Err<Self>) -> nom::Err<Self> {
move |e: nom::Err<Self>| e.map(|e| e.set_parse_context(msg))
}
}
impl ParseError<&[u8]> for Error {
fn from_error_kind(input: &[u8], _kind: nom::error::ErrorKind) -> Self {
Error::NomDetail(input.into(), "parse error")
}
fn append(_: &[u8], _: nom::error::ErrorKind, other: Self) -> Self {
other
}
}
impl From<nom::Err<Error>> for Error {
fn from(e: nom::Err<Error>) -> Self {
match e {
nom::Err::Error(err) | nom::Err::Failure(err) => Error::Nom(err.to_string()),
nom::Err::Incomplete(_) => unreachable!("we do not implement streaming parsers"),
}
}
}
}

9
git-object/src/immutable/parse.rs

@ -1,7 +1,3 @@
use crate::{
immutable::{decode, Signature},
ByteSlice, Sign, Time,
};
use bstr::{BStr, BString, ByteVec};
use btoi::btoi;
use nom::{
@ -14,6 +10,11 @@ use nom::{
IResult,
};
use crate::{
immutable::{object::decode, Signature},
ByteSlice, Sign, Time,
};
pub(crate) const NL: &[u8] = b"\n";
pub(crate) const SPACE: &[u8] = b" ";
pub(crate) const SPACE_OR_NL: &[u8] = b" \n";

9
git-object/src/immutable/tag.rs

@ -1,7 +1,3 @@
use crate::{
immutable::{decode, parse, parse::NL, Signature},
BStr, ByteSlice,
};
use nom::bytes::complete::take_while;
use nom::{
branch::alt,
@ -12,6 +8,11 @@ use nom::{
IResult,
};
use crate::{
immutable::{object::decode, parse, parse::NL, Signature},
BStr, ByteSlice,
};
/// Represents a git tag, commonly indicating a software release.
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]

5
git-object/src/immutable/tree.rs

@ -1,5 +1,7 @@
use std::convert::TryFrom;
use crate::{
immutable::{decode, parse::SPACE},
immutable::{object::decode, parse::SPACE},
tree,
};
use bstr::{BStr, ByteSlice};
@ -11,7 +13,6 @@ use nom::{
sequence::terminated,
IResult,
};
use std::convert::TryFrom;
/// A directory snapshot containing files (blobs), directories (trees) and submodules (commits).
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]

4
git-odb/src/borrowed.rs

@ -1,5 +1,7 @@
//! Contains a borrowed Object bound to a buffer holding its decompressed data.
use git_object::immutable;
/// A borrowed object using a borrowed slice as backing buffer.
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
pub struct Object<'a> {
@ -15,7 +17,7 @@ impl<'a> Object<'a> {
///
/// **Note** that [mutable, decoded objects][git_object::mutable::Object] can be created from a [`crate::borrowed::Object`]
/// using [`git_object::immutable::Object::into_mutable()`].
pub fn decode(&self) -> Result<git_object::immutable::Object<'_>, git_object::immutable::decode::Error> {
pub fn decode(&self) -> Result<git_object::immutable::Object<'_>, immutable::object::decode::Error> {
Ok(match self.kind {
git_object::Kind::Tree => {
git_object::immutable::Object::Tree(git_object::immutable::Tree::from_bytes(self.data)?)

8
git-odb/src/pack/index/verify.rs

@ -1,11 +1,13 @@
use crate::pack::{self, index};
use git_features::progress::{self, Progress};
use git_hash::SIZE_OF_SHA1_DIGEST as SHA1_SIZE;
use git_object::{
bstr::{BString, ByteSlice},
immutable, mutable,
immutable::object,
mutable,
};
use crate::pack::{self, index};
/// Returned by [`index::File::verify_checksum()`]
#[derive(thiserror::Error, Debug)]
#[allow(missing_docs)]
@ -17,7 +19,7 @@ pub enum Error {
},
#[error("{kind} object {id} could not be decoded")]
ObjectDecode {
source: immutable::decode::Error,
source: object::decode::Error,
kind: git_object::Kind,
id: git_hash::ObjectId,
},

9
git-odb/src/traverse.rs

@ -4,8 +4,11 @@
pub mod ancestors {
use crate::{compound, linked, pack};
use git_hash::ObjectId;
use std::borrow::Borrow;
use std::{collections::BTreeSet, collections::VecDeque};
use git_object::immutable;
use std::{
borrow::Borrow,
collections::{BTreeSet, VecDeque},
};
/// The error used in the iterator implementation of [Iter].
#[derive(Debug, thiserror::Error)]
@ -14,7 +17,7 @@ pub mod ancestors {
#[error(transparent)]
Compound(#[from] compound::locate::Error),
#[error(transparent)]
ObjectDecode(#[from] git_object::immutable::decode::Error),
ObjectDecode(#[from] immutable::object::decode::Error),
#[error("Object id {oid} wasn't found in object database")]
NotFound { oid: ObjectId },
}

Loading…
Cancel
Save