1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use gix_features::fs;
use crate::store_impls::loose;
pub type Error = gix_features::fs::walkdir::Error;
impl loose::Iter {
fn path_to_id(
&self,
res: Result<fs::walkdir::DirEntry, fs::walkdir::Error>,
) -> Option<Result<gix_hash::ObjectId, Error>> {
use std::path::Component::Normal;
match res {
Ok(e) => {
let p = e.path();
let mut ci = p.components();
let (c2, c1) = (ci.next_back(), ci.next_back());
if let (Some(Normal(c1)), Some(Normal(c2))) = (c1, c2) {
if c1.len() == 2 && c2.len() == self.hash_hex_len - 2 {
if let (Some(c1), Some(c2)) = (c1.to_str(), c2.to_str()) {
let mut buf = gix_hash::Kind::hex_buf();
{
let (first_byte, rest) = buf[..self.hash_hex_len].split_at_mut(2);
first_byte.copy_from_slice(c1.as_bytes());
rest.copy_from_slice(c2.as_bytes());
}
if let Ok(b) = gix_hash::ObjectId::from_hex(&buf[..self.hash_hex_len]) {
return Some(Ok(b));
}
}
}
}
}
Err(err) => return Some(Err(err)),
};
None
}
}
impl Iterator for loose::Iter {
type Item = Result<gix_hash::ObjectId, Error>;
fn next(&mut self) -> Option<Self::Item> {
while let Some(res) = self.inner.next() {
if let Some(res) = self.path_to_id(res) {
return Some(res);
}
}
None
}
}
impl loose::Store {
pub fn iter(&self) -> loose::Iter {
loose::Iter {
inner: fs::walkdir_new(
&self.path,
fs::walkdir::Parallelism::ThreadPoolPerTraversal {
thread_name: "gix_odb::loose::Store::iter: fs-walk",
},
)
.min_depth(2)
.max_depth(3)
.follow_links(false)
.into_iter(),
hash_hex_len: self.object_hash.len_in_hex(),
}
}
}