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 143 144 145 146 147 148 149 150 151 152 153 154 155
//! 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 memmap2::Mmap;
/// The version of an index file
#[derive(Default, PartialEq, Eq, Ord, PartialOrd, Debug, Hash, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[allow(missing_docs)]
pub enum Version {
V1 = 1,
#[default]
V2 = 2,
}
impl Version {
/// The kind of hash to produce to be compatible to this kind of index
pub fn hash(&self) -> gix_hash::Kind {
match self {
Version::V1 | Version::V2 => gix_hash::Kind::Sha1,
}
}
}
/// A way to indicate if a lookup, despite successful, was ambiguous or yielded exactly
/// one result in the particular index.
pub type PrefixLookupResult = Result<EntryIndex, ()>;
/// The type for referring to indices of an entry within the index file.
pub type EntryIndex = u32;
const FAN_LEN: usize = 256;
/// A representation of a pack index file
pub struct File {
data: Mmap,
path: std::path::PathBuf,
version: Version,
num_objects: u32,
fan: [u32; FAN_LEN],
hash_len: usize,
object_hash: gix_hash::Kind,
}
/// 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, as one past the highest entry index.
pub fn num_objects(&self) -> EntryIndex {
self.num_objects
}
/// The kind of hash we assume
pub fn object_hash(&self) -> gix_hash::Kind {
self.object_hash
}
}
const V2_SIGNATURE: &[u8] = b"\xfftOc";
///
#[allow(clippy::empty_docs)]
pub mod init;
pub(crate) mod access;
pub use access::Entry;
pub(crate) mod encode;
///
#[allow(clippy::empty_docs)]
pub mod traverse;
mod util;
///
#[allow(clippy::empty_docs)]
pub mod verify;
///
#[cfg(feature = "streaming-input")]
pub mod write;