use git_features::fs; use crate::store_impls::loose; /// Returned by [`loose::Store::iter()`] pub type Error = git_features::fs::walkdir::Error; impl loose::Iter { fn path_to_id( &self, res: Result, ) -> Option> { 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 = git_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) = git_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; fn next(&mut self) -> Option { while let Some(res) = self.inner.next() { if let Some(res) = self.path_to_id(res) { return Some(res); } } None } } /// Iteration and traversal impl loose::Store { /// Return an iterator over all objects contained in the database. /// /// The [`Id`][git_hash::ObjectId]s returned by the iterator can typically be used in the [`locate(…)`][loose::Store::try_find()] method. /// _Note_ that the result is not sorted or stable, thus ordering can change between runs. /// /// # Notes /// /// [`loose::Iter`] is used instead of `impl Iterator<…>` to allow using this iterator in struct fields, as is currently /// needed if iterators need to be implemented by hand in the absence of generators. pub fn iter(&self) -> loose::Iter { loose::Iter { inner: fs::walkdir_new(&self.path) .min_depth(2) .max_depth(3) .follow_links(false) .into_iter(), hash_hex_len: self.object_hash.len_in_hex(), } } }