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
/// A way to indicate if a lookup, despite successful, was ambiguous or yielded exactly
/// one result in the particular index.
// TODO: find better name, ambiguous with git_pack::index::PrefixLookupResult (entry_index inside)
pub type PrefixLookupResult = Result<git_hash::ObjectId, ()>;

/// A potentially ambiguous prefix for use with `Handle::disambiguate_prefix()`.
#[derive(Debug, Copy, Clone)]
pub struct PotentialPrefix {
    id: git_hash::ObjectId,
    hex_len: usize,
}

impl PotentialPrefix {
    /// Create a new potentially ambiguous prefix from an `id` and the desired minimal `hex_len`.
    ///
    /// It is considered ambiguous until it's disambiguated by validating that there is only a single object
    /// matching this prefix.
    pub fn new(id: impl Into<git_hash::ObjectId>, hex_len: usize) -> Result<Self, git_hash::prefix::Error> {
        let id = id.into();
        git_hash::Prefix::new(&id, hex_len)?;
        Ok(PotentialPrefix { id, hex_len })
    }

    /// Transform ourselves into a `Prefix` with our current hex lengths.
    pub fn to_prefix(&self) -> git_hash::Prefix {
        git_hash::Prefix::new(self.id, self.hex_len).expect("our hex-len to always be in bounds")
    }

    pub(crate) fn inc_hex_len(&mut self) {
        self.hex_len += 1;
        assert!(self.hex_len <= self.id.kind().len_in_hex());
    }

    pub(crate) fn id(&self) -> &git_hash::oid {
        &self.id
    }

    pub(crate) fn hex_len(&self) -> usize {
        self.hex_len
    }
}

///
pub mod existing {
    use git_hash::ObjectId;

    /// The error returned by the [`find(…)`][crate::FindExt::find()] trait methods.
    #[derive(Debug, thiserror::Error)]
    #[allow(missing_docs)]
    pub enum Error<T: std::error::Error + 'static> {
        #[error(transparent)]
        Find(T),
        #[error("An object with id {} could not be found", .oid)]
        NotFound { oid: ObjectId },
    }
}

///
pub mod existing_object {
    use git_hash::ObjectId;

    /// The error returned by the various [`find_*()`][crate::FindExt::find_commit()] trait methods.
    #[derive(Debug, thiserror::Error)]
    #[allow(missing_docs)]
    pub enum Error<T: std::error::Error + 'static> {
        #[error(transparent)]
        Find(T),
        #[error(transparent)]
        Decode(git_object::decode::Error),
        #[error("An object with id {oid} could not be found")]
        NotFound { oid: ObjectId },
        #[error("Expected object of kind {expected}")]
        ObjectKind { expected: git_object::Kind },
    }
}

///
pub mod existing_iter {
    use git_hash::ObjectId;

    /// The error returned by the various [`find_*_iter()`][crate::FindExt::find_commit_iter()] trait methods.
    #[derive(Debug, thiserror::Error)]
    #[allow(missing_docs)]
    pub enum Error<T: std::error::Error + 'static> {
        #[error(transparent)]
        Find(T),
        #[error("An object with id {oid} could not be found")]
        NotFound { oid: ObjectId },
        #[error("Expected object of kind {expected}")]
        ObjectKind { expected: git_object::Kind },
    }
}