Skip to content

Commit 0c68131

Browse files
committed
feat!: use gix-error instead of thiserror
1 parent 08f9ed4 commit 0c68131

7 files changed

Lines changed: 51 additions & 101 deletions

File tree

Cargo.lock

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gix-chunk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ doctest = false
1717
test = false
1818

1919
[dependencies]
20-
thiserror = "2.0.17"
20+
gix-error = { version = "^0.0.0", path = "../gix-error" }

gix-chunk/src/file/decode.rs

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,60 @@
1+
use gix_error::bstr::ByteSlice;
2+
use gix_error::ParseError;
13
use std::ops::Range;
24

3-
mod error {
4-
/// The value returned by [`crate::file::Index::from_bytes()`]
5-
#[derive(Debug, thiserror::Error)]
6-
#[allow(missing_docs)]
7-
pub enum Error {
8-
#[error("Sentinel value encountered while still processing chunks.")]
9-
EarlySentinelValue,
10-
#[error("Sentinel value wasn't found, saw {:?}", std::str::from_utf8(actual.as_ref()).unwrap_or("<non-ascii>"))]
11-
MissingSentinelValue { actual: crate::Id },
12-
#[error("The chunk offset {offset} went past the file of length {file_length} - was it truncated?")]
13-
ChunkSizeOutOfBounds {
14-
offset: crate::file::Offset,
15-
file_length: u64,
16-
},
17-
#[error("All chunk offsets must be incrementing.")]
18-
NonIncrementalChunkOffsets,
19-
#[error("The chunk of kind {:?} was encountered more than once", std::str::from_utf8(kind.as_ref()).unwrap_or("<non-ascii>"))]
20-
DuplicateChunk { kind: crate::Id },
21-
#[error("The table of contents would be {expected} bytes, but got only {actual}")]
22-
TocTooSmall { actual: usize, expected: usize },
23-
#[error("Empty chunk indices are not allowed as the point of chunked files is to have chunks.")]
24-
Empty,
25-
}
26-
}
27-
pub use error::Error;
28-
295
use crate::{file, file::index};
306

317
impl file::Index {
328
/// Provided a mapped file at the beginning via `data`, starting at `toc_offset` decode all chunk information to return
339
/// an index with `num_chunks` chunks.
34-
pub fn from_bytes(data: &[u8], toc_offset: usize, num_chunks: u32) -> Result<Self, Error> {
10+
pub fn from_bytes(data: &[u8], toc_offset: usize, num_chunks: u32) -> Result<Self, ParseError> {
3511
if num_chunks == 0 {
36-
return Err(Error::Empty);
12+
return Err(ParseError::new(
13+
"Empty chunk indices are not allowed as the point of chunked files is to have chunks.",
14+
));
3715
}
3816

3917
let data_len: u64 = data.len() as u64;
4018
let mut chunks = Vec::with_capacity(num_chunks as usize);
4119
let mut toc_entry = &data[toc_offset..];
4220
let expected_min_size = (num_chunks as usize + 1) * file::Index::ENTRY_SIZE;
4321
if toc_entry.len() < expected_min_size {
44-
return Err(Error::TocTooSmall {
45-
expected: expected_min_size,
46-
actual: toc_entry.len(),
47-
});
22+
return Err(format!(
23+
"The table of contents would be {expected_min_size} bytes, but got only {toc_entry_len}",
24+
toc_entry_len = toc_entry.len()
25+
))?;
4826
}
4927

50-
for _ in 0..num_chunks {
28+
for chunk_idx in 0..num_chunks {
5129
let (kind, offset) = toc_entry.split_at(4);
5230
let kind = to_kind(kind);
5331
if kind == crate::SENTINEL {
54-
return Err(Error::EarlySentinelValue);
32+
return Err(format!(
33+
"Sentinel value encountered while processing chunks {chunk_idx} of {num_chunks}"
34+
))?;
5535
}
5636
if chunks.iter().any(|c: &index::Entry| c.kind == kind) {
57-
return Err(Error::DuplicateChunk { kind });
37+
return Err(format!(
38+
"The chunk of kind '{}' was encountered more than once",
39+
kind.as_bstr()
40+
))?;
5841
}
5942

6043
let offset = be_u64(offset);
6144
if offset > data_len {
62-
return Err(Error::ChunkSizeOutOfBounds {
63-
offset,
64-
file_length: data_len,
65-
});
45+
return Err(format!(
46+
"The chunk offset {offset} went past the file of length {data_len} - was it truncated?",
47+
))?;
6648
}
6749
toc_entry = &toc_entry[file::Index::ENTRY_SIZE..];
6850
let next_offset = be_u64(&toc_entry[4..]);
6951
if next_offset > data_len {
70-
return Err(Error::ChunkSizeOutOfBounds {
71-
offset: next_offset,
72-
file_length: data_len,
73-
});
52+
return Err(format!(
53+
"The chunk offset {next_offset} went past the file of length {data_len} - was it truncated?"
54+
))?;
7455
}
7556
if next_offset <= offset {
76-
return Err(Error::NonIncrementalChunkOffsets);
57+
return Err("All chunk offsets must be incrementing.")?;
7758
}
7859
chunks.push(index::Entry {
7960
kind,
@@ -86,7 +67,7 @@ impl file::Index {
8667

8768
let sentinel = to_kind(&toc_entry[..4]);
8869
if sentinel != crate::SENTINEL {
89-
return Err(Error::MissingSentinelValue { actual: sentinel });
70+
return Err(format!("Sentinel value wasn't found, saw '{}'", sentinel.as_bstr()))?;
9071
}
9172

9273
Ok(file::Index {

gix-chunk/src/file/index.rs

Lines changed: 18 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,14 @@
11
use std::ops::Range;
22

33
use crate::file::Index;
4-
5-
///
6-
pub mod offset_by_kind {
7-
use std::fmt::{Display, Formatter};
8-
9-
/// The error returned by [`Index::offset_by_id()`][super::Index::offset_by_id()].
10-
#[allow(missing_docs)]
11-
#[derive(Debug)]
12-
pub struct Error {
13-
pub kind: crate::Id,
14-
}
15-
16-
impl Display for Error {
17-
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
18-
write!(
19-
f,
20-
"Chunk named {:?} was not found in chunk file index",
21-
std::str::from_utf8(&self.kind).unwrap_or("<non-ascii>")
22-
)
23-
}
24-
}
25-
26-
impl std::error::Error for Error {}
27-
}
28-
29-
///
30-
pub mod data_by_kind {
31-
/// The error returned by [`Index::data_by_id()`][super::Index::data_by_id()].
32-
#[derive(Debug, thiserror::Error)]
33-
#[allow(missing_docs)]
34-
pub enum Error {
35-
#[error("The chunk wasn't found in the file index")]
36-
NotFound(#[from] super::offset_by_kind::Error),
37-
#[error("The offsets into the file couldn't be represented by usize")]
38-
FileTooLarge,
39-
}
40-
}
4+
use crate::Id;
5+
use gix_error::bstr::ByteSlice;
6+
use gix_error::{message, Message};
417

428
/// An entry of a chunk file index
439
pub struct Entry {
4410
/// The kind of the chunk file
45-
pub kind: crate::Id,
11+
pub kind: Id,
4612
/// The offset, relative to the beginning of the file, at which to find the chunk and its end.
4713
pub offset: Range<crate::file::Offset>,
4814
}
@@ -59,11 +25,11 @@ impl Index {
5925
}
6026

6127
/// Find a chunk of `kind` and return its offset into the data if found
62-
pub fn offset_by_id(&self, kind: crate::Id) -> Result<Range<crate::file::Offset>, offset_by_kind::Error> {
28+
pub fn offset_by_id(&self, kind: Id) -> Result<Range<crate::file::Offset>, Message> {
6329
self.chunks
6430
.iter()
6531
.find_map(|c| (c.kind == kind).then(|| c.offset.clone()))
66-
.ok_or(offset_by_kind::Error { kind })
32+
.ok_or_else(make_message(kind))
6733
}
6834

6935
/// Find a chunk of `kind` and return its offset as usize range into the data if found.
@@ -73,30 +39,31 @@ impl Index {
7339
///
7440
/// - if the usize conversion fails, which isn't expected as memory maps can't be created if files are too large
7541
/// to require such offsets.
76-
pub fn usize_offset_by_id(&self, kind: crate::Id) -> Result<Range<usize>, offset_by_kind::Error> {
42+
pub fn usize_offset_by_id(&self, kind: Id) -> Result<Range<usize>, Message> {
7743
self.chunks
7844
.iter()
7945
.find_map(|c| (c.kind == kind).then(|| crate::range::into_usize_or_panic(c.offset.clone())))
80-
.ok_or(offset_by_kind::Error { kind })
46+
.ok_or_else(make_message(kind))
8147
}
8248

8349
/// Like [`Index::usize_offset_by_id()`] but with support for validation and transformation using a function.
8450
pub fn validated_usize_offset_by_id<T>(
8551
&self,
86-
kind: crate::Id,
52+
kind: Id,
8753
validate: impl FnOnce(Range<usize>) -> T,
88-
) -> Result<T, offset_by_kind::Error> {
54+
) -> Result<T, Message> {
8955
self.chunks
9056
.iter()
9157
.find_map(|c| (c.kind == kind).then(|| crate::range::into_usize_or_panic(c.offset.clone())))
9258
.map(validate)
93-
.ok_or(offset_by_kind::Error { kind })
59+
.ok_or_else(make_message(kind))
9460
}
9561

9662
/// Find a chunk of `kind` and return its data slice based on its offset.
97-
pub fn data_by_id<'a>(&self, data: &'a [u8], kind: crate::Id) -> Result<&'a [u8], data_by_kind::Error> {
63+
pub fn data_by_id<'a>(&self, data: &'a [u8], kind: Id) -> Result<&'a [u8], Message> {
9864
let offset = self.offset_by_id(kind)?;
99-
Ok(&data[crate::range::into_usize(offset).ok_or(data_by_kind::Error::FileTooLarge)?])
65+
Ok(&data[crate::range::into_usize(offset)
66+
.ok_or_else(|| message!("The offsets into the file couldn't be represented by usize"))?])
10067
}
10168

10269
/// Return the end offset lf the last chunk, which is the highest offset as well.
@@ -105,3 +72,7 @@ impl Index {
10572
self.chunks.last().expect("at least one chunk").offset.end
10673
}
10774
}
75+
76+
fn make_message(kind: Id) -> impl FnOnce() -> Message {
77+
move || message!("Chunk named '{}' was not found in chunk file index", kind.as_bstr())
78+
}

gix-chunk/src/file/write.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ mod write_chunk {
6060
"BUG: expected to write {} bytes, but only wrote {} for chunk {:?}",
6161
entry.offset.end,
6262
self.written_bytes,
63-
std::str::from_utf8(&entry.kind)
63+
(&entry.kind)
6464
);
6565
}
6666
self.written_bytes = 0;
@@ -87,7 +87,7 @@ impl Index {
8787
assert!(
8888
!self.chunks.iter().any(|e| e.kind == chunk),
8989
"BUG: must not add chunk of same kind twice: {:?}",
90-
std::str::from_utf8(&chunk)
90+
(&chunk)
9191
);
9292
self.chunks.push(Entry {
9393
kind: chunk,

gix-pack/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ gix-features = { version = "^0.45.2", path = "../gix-features", features = ["crc
3838
gix-path = { version = "^0.10.22", path = "../gix-path" }
3939
gix-hash = { version = "^0.21.2", path = "../gix-hash" }
4040
gix-chunk = { version = "^0.4.12", path = "../gix-chunk" }
41+
gix-error = { version = "^0.0.0", path = "../gix-error" }
4142
gix-object = { version = "^0.54.1", path = "../gix-object" }
4243
gix-hashtable = { version = "^0.11.0", path = "../gix-hashtable", optional = true }
4344

gix-pack/src/multi_index/init.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,7 @@ mod error {
2121
#[error("Unsupported hash kind: {kind})")]
2222
UnsupportedObjectHash { kind: u8 },
2323
#[error(transparent)]
24-
ChunkFileDecode(#[from] gix_chunk::file::decode::Error),
25-
#[error(transparent)]
26-
MissingChunk(#[from] gix_chunk::file::index::offset_by_kind::Error),
27-
#[error(transparent)]
28-
FileTooLarge(#[from] gix_chunk::file::index::data_by_kind::Error),
24+
ChunkFileDecode(#[from] gix_error::ParseError),
2925
#[error("The multi-pack fan doesn't have the correct size of 256 * 4 bytes")]
3026
MultiPackFanSize,
3127
#[error(transparent)]

0 commit comments

Comments
 (0)