Skip to content

Commit

Permalink
possibly a step towards solving this traversal… (#301)
Browse files Browse the repository at this point in the history
…but currently it for all the right reason won't borrow-check.
Can this be much simpler?
  • Loading branch information
Byron committed May 18, 2022
1 parent 200384c commit c64a77f
Showing 1 changed file with 51 additions and 33 deletions.
84 changes: 51 additions & 33 deletions git-ref/src/store/file/overlay_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,41 @@ impl<'p, 's> Iterator for LooseThenPacked<'p, 's> {
type Item = Result<Reference, Error>;

fn next(&mut self) -> Option<Self::Item> {
enum Kind {
GitDir,
CommonDir,
}
fn advance_to_non_private(iter: &mut Peekable<SortedLoosePaths>) {
while let Some(Ok((_path, name))) = iter.peek() {
if name.category().map_or(true, |cat| cat.is_worktree_private()) {
iter.next();
}
}
}

fn peek_loose<'a>(
git_dir: &'a mut Peekable<SortedLoosePaths>,
_common_dir: Option<&'a mut Peekable<SortedLoosePaths>>,
) -> Option<&'a std::io::Result<(PathBuf, FullName)>> {
git_dir.peek()
}
fn next_loose(
git_dir: &mut Peekable<SortedLoosePaths>,
_common_dir: Option<&mut Peekable<SortedLoosePaths>>,
) -> Option<std::io::Result<(PathBuf, FullName)>> {
git_dir.next()
common_dir: Option<&'a mut Peekable<SortedLoosePaths>>,
) -> Option<(
&'a std::io::Result<(PathBuf, FullName)>,
&'a mut Peekable<SortedLoosePaths>,
)> {
match common_dir {
Some(common_dir) => match (git_dir.peek(), {
advance_to_non_private(common_dir);
common_dir.peek()
}) {
(None, None) => None,
(None, Some(res)) | (Some(_), Some(res @ Err(_))) => Some((res, common_dir)),
(Some(res), None) | (Some(res @ Err(_)), Some(_)) => Some((res, git_dir)),
(Some(Ok((_, git_dir_name))), Some(Ok((_, common_dir_name)))) => {
match git_dir_name.cmp(&common_dir_name) {
_ => todo!(),
}
}
},
None => git_dir.peek().map(|r| (r, git_dir)),
}
}
match self.iter_packed.as_mut() {
Some(packed_iter) => match (
Expand All @@ -120,34 +144,28 @@ impl<'p, 's> Iterator for LooseThenPacked<'p, 's> {
let res = packed_iter.next().expect("peeked value exists");
Some(self.convert_packed(res))
}
(Some(_), None) | (Some(Err(_)), Some(_)) => {
let res = next_loose(&mut self.iter_git_dir, self.iter_common_dir.as_mut()).expect("prior peek");
(Some((_, iter)), None) | (Some((Err(_), iter)), Some(_)) => {
let res = iter.next().expect("prior peek");
Some(self.convert_loose(res))
}
(Some(Ok(loose)), Some(Ok(packed))) => {
let loose_name = loose.1.as_bstr();
match loose_name.cmp(packed.name.as_bstr()) {
Ordering::Less => {
let res =
next_loose(&mut self.iter_git_dir, self.iter_common_dir.as_mut()).expect("prior peek");
Some(self.convert_loose(res))
}
Ordering::Equal => {
drop(packed_iter.next());
let res =
next_loose(&mut self.iter_git_dir, self.iter_common_dir.as_mut()).expect("prior peek");
Some(self.convert_loose(res))
}
Ordering::Greater => {
let res = packed_iter.next().expect("name retrieval configured");
Some(self.convert_packed(res))
}
(Some((Ok((_, loose_name)), iter)), Some(Ok(packed))) => match loose_name.as_ref().cmp(packed.name) {
Ordering::Less => {
let res = iter.next().expect("prior peek");
Some(self.convert_loose(res))
}
}
Ordering::Equal => {
drop(packed_iter.next());
let res = iter.next().expect("prior peek");
Some(self.convert_loose(res))
}
Ordering::Greater => {
let res = packed_iter.next().expect("name retrieval configured");
Some(self.convert_packed(res))
}
},
},
None => {
next_loose(&mut self.iter_git_dir, self.iter_common_dir.as_mut()).map(|res| self.convert_loose(res))
}
None => peek_loose(&mut self.iter_git_dir, self.iter_common_dir.as_mut())
.and_then(|(_, iter)| iter.next().map(|res| self.convert_loose(res))),
}
}
}
Expand Down

0 comments on commit c64a77f

Please sign in to comment.