Skip to content

Commit b7a4d17

Browse files
committed
Implement object Id as newtype for more convenenience and…
…to cut extra dependencies to 'hex', which are now all handled by the ID type.
1 parent 0f24066 commit b7a4d17

File tree

16 files changed

+66
-49
lines changed

16 files changed

+66
-49
lines changed

Cargo.lock

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

demos/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,5 @@ test = false
1313

1414
[dependencies]
1515
git-odb = { version = "0.1.0", path = "../gitoxide-odb" }
16-
hex = "0.3.2"
1716
rayon = "1.3.0"
1817
anyhow = "1.0.31"

demos/git-count.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ fn run() -> Result<()> {
3434
index.kind(),
3535
index.num_objects(),
3636
index.version(),
37-
hex::encode(index.checksum_of_index()),
38-
hex::encode(index.checksum_of_pack()),
37+
index.checksum_of_index(),
38+
index.checksum_of_pack(),
3939
)?;
4040

4141
let (deltas, commits, trees, blobs, tags) = index

gitoxide-object/src/borrowed/commit.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use crate::borrowed::{
55
Signature,
66
};
77
use bstr::{BStr, ByteSlice};
8-
use hex::FromHex;
98
use nom::{
109
branch::alt,
1110
bytes::{complete::is_not, complete::tag},
@@ -79,7 +78,7 @@ pub fn parse(i: &[u8]) -> IResult<&[u8], Commit, Error> {
7978

8079
impl<'data> Commit<'data> {
8180
pub fn tree(&self) -> crate::Id {
82-
<[u8; 20]>::from_hex(self.tree).expect("prior validation")
81+
crate::Id::from_hex(self.tree).expect("prior validation")
8382
}
8483
pub fn from_bytes(d: &'data [u8]) -> Result<Commit<'data>, Error> {
8584
parse(d).map(|(_, t)| t).map_err(Error::from)

gitoxide-object/src/borrowed/tag.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::borrowed::{
44
Signature,
55
};
66
use bstr::{BStr, ByteSlice};
7-
use hex::FromHex;
87
use nom::{
98
branch::alt,
109
bytes::complete::{tag, take_until, take_while1},
@@ -105,7 +104,7 @@ fn parse_message(i: &[u8]) -> IResult<&[u8], (&BStr, Option<&BStr>), Error> {
105104

106105
impl<'data> Tag<'data> {
107106
pub fn target(&self) -> crate::Id {
108-
<[u8; 20]>::from_hex(self.target).expect("prior validation")
107+
crate::Id::from_hex(self.target).expect("prior validation")
109108
}
110109
pub fn from_bytes(d: &'data [u8]) -> Result<Tag<'data>, Error> {
111110
parse(d).map(|(_, t)| t).map_err(Error::from)

gitoxide-object/src/types.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use bstr::ByteSlice;
2+
use nom::lib::std::fmt::Formatter;
13
use quick_error::quick_error;
24

35
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
@@ -19,12 +21,36 @@ pub struct Time {
1921
pub const SHA1_SIZE: usize = 20;
2022

2123
/// A SHA1 identifying objects
22-
pub type Id = [u8; SHA1_SIZE];
24+
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
25+
pub struct Id(pub [u8; SHA1_SIZE]);
26+
27+
impl Id {
28+
pub fn encode_to_40_bytes_slice(&self, out: &mut [u8]) -> Result<(), hex::FromHexError> {
29+
hex::encode_to_slice(self.0, out)
30+
}
2331

24-
pub fn id_from_20_bytes(b: &[u8]) -> Id {
25-
let mut id = [0; SHA1_SIZE];
26-
id.copy_from_slice(b);
27-
id
32+
pub fn from_20_bytes(b: &[u8]) -> Id {
33+
let mut id = [0; SHA1_SIZE];
34+
id.copy_from_slice(b);
35+
Id(id)
36+
}
37+
38+
pub fn from_hex(buf: &[u8]) -> Result<Id, hex::FromHexError> {
39+
use hex::FromHex;
40+
Ok(Id(<[u8; 20]>::from_hex(buf)?))
41+
}
42+
43+
pub fn null() -> Id {
44+
Id([0u8; 20])
45+
}
46+
}
47+
48+
impl std::fmt::Display for Id {
49+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
50+
let mut buf = [0u8; 40];
51+
self.encode_to_40_bytes_slice(&mut buf).unwrap();
52+
write!(f, "{}", &buf.as_bstr())
53+
}
2854
}
2955

3056
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]

gitoxide-object/tests/borrowed/tree.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
mod from_bytes {
2-
use crate::{borrowed::fixture_bytes, hex_to_id};
2+
use crate::borrowed::fixture_bytes;
33
use bstr::ByteSlice;
44
use git_object::borrowed::{Tree, TreeEntry as Entry, TreeMode as Mode};
5+
use hex::FromHex;
6+
7+
pub fn hex_to_oid(hex: &str) -> [u8; 20] {
8+
<[u8; 20]>::from_hex(hex).unwrap()
9+
}
510

611
#[test]
712
fn everything() {
@@ -12,27 +17,27 @@ mod from_bytes {
1217
Entry {
1318
mode: Mode::BlobExecutable,
1419
filename: b"exe".as_bstr(),
15-
oid: &hex_to_id("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391")[..]
20+
oid: &hex_to_oid("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391")[..]
1621
},
1722
Entry {
1823
mode: Mode::Blob,
1924
filename: b"file".as_bstr(),
20-
oid: &hex_to_id("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391")[..]
25+
oid: &hex_to_oid("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391")[..]
2126
},
2227
Entry {
2328
mode: Mode::Commit,
2429
filename: b"grit-submodule".as_bstr(),
25-
oid: &hex_to_id("b2d1b5d684bdfda5f922b466cc13d4ce2d635cf8")[..]
30+
oid: &hex_to_oid("b2d1b5d684bdfda5f922b466cc13d4ce2d635cf8")[..]
2631
},
2732
Entry {
2833
mode: Mode::Tree,
2934
filename: b"subdir".as_bstr(),
30-
oid: &hex_to_id("4d5fcadc293a348e88f777dc0920f11e7d71441c")[..]
35+
oid: &hex_to_oid("4d5fcadc293a348e88f777dc0920f11e7d71441c")[..]
3136
},
3237
Entry {
3338
mode: Mode::Link,
3439
filename: b"symlink".as_bstr(),
35-
oid: &hex_to_id("1a010b1c0f081b2e8901d55307a15c29ff30af0e")[..]
40+
oid: &hex_to_oid("1a010b1c0f081b2e8901d55307a15c29ff30af0e")[..]
3641
}
3742
]
3843
}

gitoxide-object/tests/object.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
use hex::FromHex;
21
use std::path::PathBuf;
32

43
mod borrowed;
54

6-
pub fn hex_to_id(hex: &str) -> [u8; 20] {
7-
<[u8; 20]>::from_hex(hex).unwrap()
5+
pub fn hex_to_id(hex: &str) -> git_object::Id {
6+
git_object::Id::from_hex(hex.as_bytes()).unwrap()
87
}
98

109
pub fn fixture(path: &str) -> PathBuf {

gitoxide-odb/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ doctest = false
1111
[dependencies]
1212
quick-error = "1.2.3"
1313
walkdir = "2.1.4"
14-
hex = "0.4.2"
1514
miniz_oxide = "0.3.6"
1615
smallvec = "1.3.0"
1716
filebuffer = "0.4.0"
@@ -22,3 +21,4 @@ btoi = "0.4.2"
2221
[dev-dependencies]
2322
pretty_assertions = "0.6.1"
2423
bstr = { version = "0.2.13", default-features = false, features = ["std"] }
24+
hex = "0.4.2"

gitoxide-odb/src/loose/db.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use crate::{
55
loose::{Object, HEADER_READ_COMPRESSED_BYTES, HEADER_READ_UNCOMPRESSED_BYTES},
66
zlib,
77
};
8-
use hex::FromHex;
98
use smallvec::SmallVec;
109
use std::{fs, io::Cursor, io::Read, path::PathBuf};
1110
use walkdir::WalkDir;
@@ -66,9 +65,10 @@ pub fn parse_header(input: &[u8]) -> Result<(object::Kind, usize, usize), Error>
6665
}
6766
}
6867

69-
fn sha1_path(id: &[u8; 20], mut root: PathBuf) -> PathBuf {
68+
fn sha1_path(id: &object::Id, mut root: PathBuf) -> PathBuf {
7069
let mut buf = [0u8; 40];
71-
hex::encode_to_slice(id, &mut buf).expect("no failure as everything is preset by now");
70+
id.encode_to_40_bytes_slice(&mut buf)
71+
.expect("no failure as everything is preset by now");
7272
let buf = std::str::from_utf8(&buf).expect("ascii only in hex");
7373
root.push(&buf[..2]);
7474
root.push(&buf[2..]);
@@ -102,14 +102,14 @@ impl Db {
102102
first_byte.copy_from_slice(c1.as_bytes());
103103
rest.copy_from_slice(c2.as_bytes());
104104
}
105-
if let Ok(b) = <[u8; 20]>::from_hex(&buf[..]) {
105+
if let Ok(b) = object::Id::from_hex(&buf[..]) {
106106
is_valid_path = true;
107107
return b;
108108
}
109109
}
110110
}
111111
}
112-
[0u8; 20]
112+
object::Id::null()
113113
});
114114
if is_valid_path {
115115
Some(e)

gitoxide-odb/src/pack/file/decoded.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl Header {
8383
}
8484
REF_DELTA => {
8585
let delta = RefDelta {
86-
oid: object::id_from_20_bytes(&d[consumed..consumed + SHA1_SIZE]),
86+
oid: object::Id::from_20_bytes(&d[consumed..consumed + SHA1_SIZE]),
8787
};
8888
consumed += SHA1_SIZE;
8989
delta

gitoxide-odb/src/pack/file/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,7 @@ impl File {
5959
self.num_objects
6060
}
6161
pub fn checksum(&self) -> Id {
62-
let mut v = [0u8; 20];
63-
v.copy_from_slice(&self.data[self.data.len() - SHA1_SIZE..]);
64-
v
62+
Id::from_20_bytes(&self.data[self.data.len() - SHA1_SIZE..])
6563
}
6664

6765
fn assure_v2(&self) {

gitoxide-odb/src/pack/index.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,11 @@ impl File {
141141
self.version
142142
}
143143
pub fn checksum_of_index(&self) -> object::Id {
144-
object::id_from_20_bytes(&self.data[self.data.len() - SHA1_SIZE..])
144+
object::Id::from_20_bytes(&self.data[self.data.len() - SHA1_SIZE..])
145145
}
146146
pub fn checksum_of_pack(&self) -> object::Id {
147147
let from = self.data.len() - SHA1_SIZE * 2;
148-
object::id_from_20_bytes(&self.data[from..from + SHA1_SIZE])
148+
object::Id::from_20_bytes(&self.data[from..from + SHA1_SIZE])
149149
}
150150

151151
fn offset_crc32_v2(&self) -> usize {
@@ -168,7 +168,7 @@ impl File {
168168
.map(|c| {
169169
let (ofs, oid) = c.split_at(N32_SIZE);
170170
Entry {
171-
oid: object::id_from_20_bytes(oid),
171+
oid: object::Id::from_20_bytes(oid),
172172
offset: BigEndian::read_u32(ofs) as u64,
173173
crc32: None,
174174
}
@@ -187,7 +187,7 @@ impl File {
187187
)
188188
.take(self.num_objects as usize)
189189
.map(move |(oid, crc32, ofs32)| Entry {
190-
oid: object::id_from_20_bytes(oid),
190+
oid: object::Id::from_20_bytes(oid),
191191
offset: {
192192
let ofs32 = BigEndian::read_u32(ofs32);
193193
if (ofs32 & N32_HIGH_BIT) == N32_HIGH_BIT {

gitoxide-odb/tests/odb.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
use hex::FromHex;
21
use std::path::PathBuf;
32

4-
pub fn hex_to_id(hex: &str) -> [u8; 20] {
5-
<[u8; 20]>::from_hex(hex).unwrap()
3+
pub fn hex_to_id(hex: &str) -> git_object::Id {
4+
git_object::Id::from_hex(hex.as_bytes()).unwrap()
65
}
76

87
pub fn fixture_path(path: &str) -> PathBuf {

gitoxide-odb/tests/pack/file.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ mod method {
1414
fn checksum() {
1515
let p = pack_at(SMALL_PACK);
1616
assert_eq!(
17-
hex::encode(p.checksum()),
17+
hex::encode(p.checksum().0),
1818
"0f3ea84cd1bba10c2a03d736a460635082833e59"
1919
);
2020
}

tasks.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* [x] decode tree
55
* [x] represent blob
66
* [x] stream blob
7-
* [ ] refactor ID into NewType
7+
* [x] refactor ID into NewType
88
* **pack**
99
* [ ] validate checksum
1010
* [x] decode full pack entries

0 commit comments

Comments
 (0)