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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
//! an index into the pack file //! /// From itertools /// Create an iterator running multiple iterators in lockstep. /// /// The `izip!` iterator yields elements until any subiterator /// returns `None`. /// /// This is a version of the standard ``.zip()`` that's supporting more than /// two iterators. The iterator element type is a tuple with one element /// from each of the input iterators. Just like ``.zip()``, the iteration stops /// when the shortest of the inputs reaches its end. /// /// **Note:** The result of this macro is in the general case an iterator /// composed of repeated `.zip()` and a `.map()`; it has an anonymous type. /// The special cases of one and two arguments produce the equivalent of /// `$a.into_iter()` and `$a.into_iter().zip($b)` respectively. /// /// Prefer this macro `izip!()` over [`multizip`] for the performance benefits /// of using the standard library `.zip()`. /// /// [`multizip`]: fn.multizip.html /// /// ``` /// # use itertools::izip; /// # /// # fn main() { /// /// // iterate over three sequences side-by-side /// let mut results = [0, 0, 0, 0]; /// let inputs = [3, 7, 9, 6]; /// /// for (r, index, input) in izip!(&mut results, 0..10, &inputs) { /// *r = index * 10 + input; /// } /// /// assert_eq!(results, [0 + 3, 10 + 7, 29, 36]); /// # } /// ``` macro_rules! izip { // @closure creates a tuple-flattening closure for .map() call. usage: // @closure partial_pattern => partial_tuple , rest , of , iterators // eg. izip!( @closure ((a, b), c) => (a, b, c) , dd , ee ) ( @closure $p:pat => $tup:expr ) => { |$p| $tup }; // The "b" identifier is a different identifier on each recursion level thanks to hygiene. ( @closure $p:pat => ( $($tup:tt)* ) , $_iter:expr $( , $tail:expr )* ) => { izip!(@closure ($p, b) => ( $($tup)*, b ) $( , $tail )*) }; // unary ($first:expr $(,)*) => { std::iter::IntoIterator::into_iter($first) }; // binary ($first:expr, $second:expr $(,)*) => { izip!($first) .zip($second) }; // n-ary where n > 2 ( $first:expr $( , $rest:expr )* $(,)* ) => { izip!($first) $( .zip($rest) )* .map( izip!(@closure a => (a) $( , $rest )*) ) }; } use filebuffer::FileBuffer; /// The version of an index file #[derive(PartialEq, Eq, Ord, PartialOrd, Debug, Hash, Clone, Copy)] #[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))] #[allow(missing_docs)] pub enum Version { V1 = 1, V2 = 2, } impl Default for Version { fn default() -> Self { Version::V2 } } impl Version { /// The kind of hash to produce to be compatible to this kind of index pub fn hash(&self) -> git_hash::Kind { match self { Version::V1 | Version::V2 => git_hash::Kind::Sha1, } } } const FAN_LEN: usize = 256; /// A representation of a pack index file pub struct File { pub(crate) data: FileBuffer, path: std::path::PathBuf, version: Version, num_objects: u32, fan: [u32; FAN_LEN], } /// Basic file information impl File { /// The version of the pack index pub fn version(&self) -> Version { self.version } /// The path of the opened index file pub fn path(&self) -> &std::path::Path { &self.path } /// The amount of objects stored in the pack and index pub fn num_objects(&self) -> u32 { self.num_objects } } const V2_SIGNATURE: &[u8] = b"\xfftOc"; /// pub mod init; pub(crate) mod access; pub use access::Entry; /// pub mod traverse; pub(crate) mod util; /// pub mod verify; /// pub mod write;