Skip to main content

git_async/
error.rs

1//! A module for errors which may occur during the use of `git-async`
2
3use crate::{
4    file_system::FileSystemError,
5    object::{ObjectId, ObjectType},
6    parsing::ParseError,
7    reference::RefName,
8};
9use accessory::Accessors;
10use alloc::vec::Vec;
11use miniz_oxide::inflate::TINFLStatus;
12
13#[expect(missing_docs)]
14pub type GResult<T> = core::result::Result<T, Error>;
15
16#[expect(missing_docs)]
17#[derive(Debug, Accessors)]
18pub struct UnexpectedObjectType {
19    pub id: ObjectId,
20    pub expected: ObjectType,
21    pub received: ObjectType,
22}
23
24#[expect(missing_docs)]
25#[non_exhaustive]
26#[derive(Debug)]
27pub enum Error {
28    FileSystem(FileSystemError),
29    PathError(Vec<u8>),
30    LooseObjectDecompressError {
31        #[expect(missing_docs)]
32        id: ObjectId,
33        #[expect(missing_docs)]
34        status: TINFLStatus,
35    },
36    PackObjectDecompressError {
37        #[expect(missing_docs)]
38        id: ObjectId,
39        #[expect(missing_docs)]
40        status: TINFLStatus,
41    },
42    FromHexError(hex::FromHexError),
43    UnsupportedIndexVersion,
44    CorruptIndexFile,
45    UnsupportedPackVersion,
46    CorruptPackFile,
47    MalformedPackedRefs,
48    MalformedRef(RefName),
49    RefNotFound(RefName),
50    MalformedPackObject(ObjectId),
51    MalformedObject(ObjectId),
52    ObjectParseError {
53        #[expect(missing_docs)]
54        id: ObjectId,
55        #[expect(missing_docs)]
56        snippet: Vec<u8>,
57    },
58    ObjectMissingRequiredFields(ObjectId),
59    MissingObject(ObjectId),
60    ObjectTooLarge(ObjectId),
61    UnexpectedThinPack,
62    NotAnnotatedWithRepo,
63    UnexpectedObjectType(UnexpectedObjectType),
64    DiffCanceled,
65    NotAGitRepository,
66}
67
68impl From<UnexpectedObjectType> for Error {
69    fn from(value: UnexpectedObjectType) -> Self {
70        Self::UnexpectedObjectType(value)
71    }
72}
73
74impl From<FileSystemError> for Error {
75    fn from(value: FileSystemError) -> Self {
76        Self::FileSystem(value)
77    }
78}
79
80impl From<hex::FromHexError> for Error {
81    fn from(value: hex::FromHexError) -> Self {
82        Self::FromHexError(value)
83    }
84}
85
86#[derive(Debug)]
87pub(crate) enum InternalObjectError {
88    ExternalError(Error),
89    ObjectTooLarge,
90    ParseError { snippet: Vec<u8> },
91    MissingFields,
92    MalformedPackObject,
93    PackObjectDecompressError(TINFLStatus),
94}
95
96pub(crate) type IResult<T> = core::result::Result<T, InternalObjectError>;
97
98impl From<Error> for InternalObjectError {
99    fn from(value: Error) -> Self {
100        Self::ExternalError(value)
101    }
102}
103
104impl From<ParseError> for InternalObjectError {
105    fn from(value: ParseError) -> Self {
106        match value {
107            ParseError::ParseError { input_snippet } => InternalObjectError::ParseError {
108                snippet: input_snippet,
109            },
110            ParseError::MissingFields => InternalObjectError::MissingFields,
111        }
112    }
113}
114
115impl From<FileSystemError> for InternalObjectError {
116    fn from(value: FileSystemError) -> Self {
117        Self::ExternalError(value.into())
118    }
119}
120
121pub(crate) fn annotate_with_object_id(id: ObjectId) -> impl Fn(InternalObjectError) -> Error {
122    move |internal| match internal {
123        InternalObjectError::ExternalError(error) => error,
124        InternalObjectError::ObjectTooLarge => Error::ObjectTooLarge(id),
125        InternalObjectError::MalformedPackObject => Error::MalformedPackObject(id),
126        InternalObjectError::ParseError { snippet } => Error::ObjectParseError { id, snippet },
127        InternalObjectError::MissingFields => Error::ObjectMissingRequiredFields(id),
128        InternalObjectError::PackObjectDecompressError(status) => {
129            Error::PackObjectDecompressError { id, status }
130        }
131    }
132}