gix_refspec/match_group/
types.rs

1use std::borrow::Cow;
2
3use bstr::BStr;
4use gix_hash::oid;
5
6use crate::RefSpecRef;
7
8/// A match group is able to match a list of ref specs in order while handling negation, conflicts and one to many mappings.
9#[derive(Default, Debug, Clone)]
10pub struct MatchGroup<'a> {
11    /// The specs that take part in item matching.
12    pub specs: Vec<RefSpecRef<'a>>,
13}
14
15///
16pub mod match_lhs {
17    use crate::{match_group::Mapping, MatchGroup};
18
19    /// The outcome of any matching operation of a [`MatchGroup`].
20    ///
21    /// It's used to validate and process the contained [mappings](Mapping).
22    #[derive(Debug, Clone)]
23    pub struct Outcome<'spec, 'item> {
24        /// The match group that produced this outcome.
25        pub group: MatchGroup<'spec>,
26        /// The mappings derived from matching [items](crate::match_group::Item).
27        pub mappings: Vec<Mapping<'item, 'spec>>,
28    }
29}
30
31///
32pub mod match_rhs {
33    use crate::{match_group::Mapping, MatchGroup};
34
35    /// The outcome of any matching operation of a [`MatchGroup`].
36    ///
37    /// It's used to validate and process the contained [mappings](Mapping).
38    #[derive(Debug, Clone)]
39    pub struct Outcome<'spec, 'item> {
40        /// The match group that produced this outcome.
41        pub group: MatchGroup<'spec>,
42        /// The mappings derived from matching [items](crate::match_group::Item).
43        pub mappings: Vec<Mapping<'spec, 'item>>,
44    }
45}
46
47/// An item to match, input to various matching operations.
48#[derive(Debug, Copy, Clone)]
49pub struct Item<'a> {
50    /// The full name of the references, like `refs/heads/main`
51    pub full_ref_name: &'a BStr,
52    /// The id that `full_ref_name` points to, which typically is a commit, but can also be a tag object (or anything else).
53    pub target: &'a oid,
54    /// The object an annotated tag is pointing to, if `target` is an annotated tag.
55    pub object: Option<&'a oid>,
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Hash)]
59/// The source (or left-hand) side of a mapping.
60pub enum SourceRef<'a> {
61    /// A full reference name, which is expected to be valid.
62    ///
63    /// Validity, however, is not enforced here.
64    FullName(Cow<'a, BStr>),
65    /// The name of an object that is expected to exist on the remote side.
66    /// Note that it might not be advertised by the remote but part of the object graph,
67    /// and thus gets sent in the pack. The server is expected to fail unless the desired
68    /// object is present but at some time it is merely a request by the user.
69    ObjectId(gix_hash::ObjectId),
70}
71
72impl SourceRef<'_> {
73    /// Create a fully owned instance by consuming this one.
74    pub fn into_owned(self) -> Source {
75        match self {
76            SourceRef::ObjectId(id) => Source::ObjectId(id),
77            SourceRef::FullName(name) => Source::FullName(name.into_owned().into()),
78        }
79    }
80}
81
82impl std::fmt::Display for SourceRef<'_> {
83    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84        match self {
85            SourceRef::FullName(name) => name.fmt(f),
86            SourceRef::ObjectId(id) => id.fmt(f),
87        }
88    }
89}
90
91/// The source (or left-hand) side of a mapping, which owns its name.
92pub type Source = SourceRef<'static>;
93
94/// A mapping from a remote to a local refs for fetches or local to remote refs for pushes.
95///
96/// Mappings are like edges in a graph, initially without any constraints.
97#[derive(Debug, Clone)]
98pub struct Mapping<'a, 'b> {
99    /// The index into the initial `items` list that matched against a spec.
100    pub item_index: Option<usize>,
101    /// The name of the remote side for fetches or the local one for pushes that matched.
102    pub lhs: SourceRef<'a>,
103    /// The name of the local side for fetches or the remote one for pushes that corresponds to `lhs`, if available.
104    pub rhs: Option<Cow<'b, BStr>>,
105    /// The index of the matched ref-spec as seen from the match group.
106    pub spec_index: usize,
107}
108
109impl std::hash::Hash for Mapping<'_, '_> {
110    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
111        self.lhs.hash(state);
112        self.rhs.hash(state);
113    }
114}