Skip to main content

grit_lib/
midx_error.rs

1//! Typed errors for multi-pack-index load and verification.
2
3use thiserror::Error;
4
5/// A fatal multi-pack-index condition (Git `die()` after `error:` lines).
6#[non_exhaustive]
7#[derive(Debug, Error, Clone, PartialEq, Eq)]
8pub enum MidxError {
9    /// Trailing or header signature does not match `MIDX`.
10    #[error("multi-pack-index signature 0x{found:08x} does not match signature 0x{expected:08x}")]
11    SignatureMismatch {
12        /// Value read from the file header.
13        found: u32,
14        /// Expected MIDX magic (`0x4d494458`).
15        expected: u32,
16    },
17
18    /// On-disk format version byte is not supported.
19    #[error("multi-pack-index version {version} not recognized")]
20    VersionNotRecognized {
21        /// Format version byte read from the file header.
22        version: u8,
23    },
24
25    /// Header hash-version byte does not match the repository object format.
26    #[error("multi-pack-index hash version {found} does not match version {expected}")]
27    HashVersionMismatch {
28        /// Hash version byte read from the MIDX header.
29        found: u8,
30        /// Hash version required by the repository object format.
31        expected: u8,
32    },
33
34    /// Required pack-names chunk is missing or cannot be parsed.
35    #[error("multi-pack-index required pack-name chunk missing or corrupted")]
36    RequiredPackNameChunkMissing,
37
38    /// Required OID fanout chunk is missing.
39    #[error("multi-pack-index required OID fanout chunk missing or corrupted")]
40    RequiredOidFanoutChunkMissing,
41
42    /// OID fanout chunk size is not 256 × 4 bytes.
43    #[error("multi-pack-index OID fanout is of the wrong size")]
44    OidFanoutWrongSize,
45
46    /// OID fanout table is not monotonically non-decreasing.
47    #[error("oid fanout out of order: fanout[{index}] = {first:x} > {second:x} = fanout[{next}]")]
48    OidFanoutOutOfOrder {
49        /// Zero-based fanout bucket index that violated ordering.
50        index: usize,
51        /// Fanout count at `index` (must be ≤ `second`).
52        first: u32,
53        /// Fanout count at the next bucket.
54        second: u32,
55        /// Index of the next fanout bucket (`index + 1`).
56        next: usize,
57    },
58
59    /// Required OID lookup chunk is missing.
60    #[error("multi-pack-index required OID lookup chunk missing or corrupted")]
61    RequiredOidLookupChunkMissing,
62
63    /// OID lookup chunk size does not match `num_objects × hash_len`.
64    #[error("multi-pack-index OID lookup chunk is the wrong size")]
65    OidLookupWrongSize,
66
67    /// Required object-offsets chunk is missing.
68    #[error("multi-pack-index required object offsets chunk missing or corrupted")]
69    RequiredObjectOffsetsChunkMissing,
70
71    /// Object-offsets chunk size does not match `num_objects × 8`.
72    #[error("multi-pack-index object offset chunk is the wrong size")]
73    ObjectOffsetsWrongSize,
74
75    /// A pack name in the pack-names chunk is not NUL-terminated.
76    #[error("multi-pack-index pack-name chunk is too short")]
77    PackNameChunkTooShort,
78
79    /// v1 MIDX pack names are not strictly increasing.
80    #[error("multi-pack-index pack names out of order: '{previous}' before '{name}'")]
81    PackNamesOutOfOrder {
82        /// Previous pack file name in sorted order.
83        previous: String,
84        /// Pack file name that breaks monotonic ordering.
85        name: String,
86    },
87
88    /// Large-offset chunk does not cover a referenced large offset slot.
89    #[error("multi-pack-index large offset out of bounds")]
90    LargeOffsetOutOfBounds,
91
92    /// Chunk table of contents could not be parsed (Git `die()` cases in `read_table_of_contents`).
93    #[error("{detail}")]
94    InvalidChunkTable {
95        /// Parse failure detail for the chunk table of contents.
96        detail: String,
97    },
98
99    /// Write attempted with no pack indexes to cover.
100    #[error("no packs to index")]
101    NoPacksToIndex,
102
103    /// A write requested an on-disk version other than `1` or `2` (for example through
104    /// `midx.version`).
105    #[error("cannot write multi-pack-index version {version}: only versions 1 and 2 exist")]
106    UnknownWriteVersion {
107        /// Requested version, as configured.
108        version: i64,
109    },
110
111    /// Preferred pack has no objects in the MIDX.
112    #[error("preferred pack '{pack}' is empty in multi-pack-index")]
113    PreferredPackEmpty {
114        /// Pack file basename (`.pack` suffix).
115        pack: String,
116    },
117
118    /// Preferred pack name does not appear in the pack list.
119    #[error("unknown preferred pack '{name}'")]
120    UnknownPreferredPack {
121        /// Preferred pack basename that was not found in the MIDX pack list.
122        name: String,
123    },
124
125    /// An existing MIDX names a pack whose `.pack` file is missing during rewrite.
126    #[error("could not load pack {pack_index}")]
127    ReferencedPackMissing {
128        /// Zero-based index into the MIDX pack list.
129        pack_index: usize,
130    },
131
132    /// Reachability bitmap generation for a MIDX failed.
133    #[error("multi-pack-index bitmap write failed: {detail}")]
134    BitmapWriteFailed {
135        /// Why bitmap generation or writing failed.
136        detail: String,
137    },
138}