Coverage Report

Created: 2026-08-05 07:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gitoxide/gix-attributes/src/search/mod.rs
Line
Count
Source
1
use std::collections::HashMap;
2
3
use gix_features::threading::OwnShared;
4
use smallvec::SmallVec;
5
6
use crate::{Assignment, AssignmentRef, Name};
7
8
mod attributes;
9
mod outcome;
10
mod refmap;
11
pub(crate) use refmap::RefMap;
12
13
/// A typically sized list of attributes.
14
pub type Assignments = SmallVec<[TrackedAssignment; AVERAGE_NUM_ATTRS]>;
15
16
/// A value of a [pattern mapping][gix_glob::search::pattern::Mapping],
17
/// which is either a macro definition or a set of attributes.
18
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
19
pub enum Value {
20
    /// A macro, whose name resolves to the contained assignments. Note that the name is the pattern of the mapping itself.
21
    MacroAssignments {
22
        /// The id of the macro itself, which is both an attribute as well as a set of additional attributes into which the macro
23
        /// resolves
24
        id: AttributeId,
25
        /// The attributes or assignments that the macro resolves to.
26
        assignments: Assignments,
27
    },
28
    /// A set of assignments which are the attributes themselves.
29
    Assignments(Assignments),
30
}
31
32
/// A way to have an assignment (`attr=value`) but also associated it with an id that allows perfect mapping
33
/// to tracking information.
34
/// Note that the order is produced after the files are parsed as global ordering is needed that goes beyond the scope of a
35
/// single `Search` instance.
36
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
37
pub struct TrackedAssignment {
38
    /// The order of the assignment.
39
    pub id: AttributeId,
40
    /// The actual assignment information.
41
    pub inner: Assignment,
42
}
43
44
/// An implementation of the [`Pattern`][gix_glob::search::Pattern] trait for attributes.
45
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Default)]
46
pub struct Attributes;
47
48
/// Describes a matching pattern with
49
#[derive(Clone, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
50
pub struct Match<'a> {
51
    /// The glob pattern itself, like `/target/*`.
52
    pub pattern: &'a gix_glob::Pattern,
53
    /// The key=value pair of the attribute that matched at the pattern. There can be multiple matches per pattern.
54
    pub assignment: AssignmentRef<'a>,
55
    /// Additional information about the kind of match.
56
    pub kind: MatchKind,
57
    /// Information about the location of the match.
58
    pub location: MatchLocation<'a>,
59
}
60
61
/// Describes in which what file and line the match was found.
62
#[derive(Clone, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
63
pub struct MatchLocation<'a> {
64
    /// The path to the source from which the pattern was loaded, or `None` if it was specified by other means.
65
    pub source: Option<&'a std::path::Path>,
66
    /// The line at which the pattern was found in its `source` file, or the occurrence in which it was provided.
67
    pub sequence_number: usize,
68
}
69
70
/// The kind of attribute within the context of a [match][Match].
71
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
72
pub enum MatchKind {
73
    /// A attribute.
74
    Attribute {
75
        /// The location of the macro which referred to it the list with all in-order attributes and macros, or `None` if
76
        /// this is attribute wasn't resolved.
77
        ///
78
        /// Use [`Outcome::match_by_id()`] to retrieve the macro.
79
        macro_id: Option<AttributeId>,
80
    },
81
    /// The attribute is a macro, which will resolve into one or more attributes or macros.
82
    Macro {
83
        /// The location of the parent macro which referred to this one in the list with all in-order attributes and macros,
84
        /// or `None` if this is macro wasn't resolved by another one.
85
        ///
86
        /// Use [`Outcome::match_by_id()`] to retrieve the parent.
87
        parent_macro_id: Option<AttributeId>,
88
    },
89
}
90
91
/// The result of a search, containing all matching attributes.
92
#[derive(Default, Clone)]
93
pub struct Outcome {
94
    /// The list of all available attributes, by ascending order. Each slots index corresponds to an attribute with that order, i.e.
95
    /// `arr[attr.id] = <attr info>`.
96
    ///
97
    /// This list needs to be up-to-date with the search group so all possible attribute names are known.
98
    matches_by_id: Vec<Slot>,
99
    /// A stack of attributes to use for processing attributes of matched patterns and for resolving their macros.
100
    attrs_stack: SmallVec<[(AttributeId, Assignment, Option<AttributeId>); 8]>,
101
    /// A set of attributes we should limit ourselves to, or empty if we should fill in all attributes, made of
102
    selected: SmallVec<[(OwnShared<str>, Option<AttributeId>); AVERAGE_NUM_ATTRS]>,
103
    /// storage for all patterns we have matched so far (in order to avoid referencing them, we copy them, but only once).
104
    patterns: RefMap<gix_glob::Pattern>,
105
    /// storage for all assignments we have matched so far (in order to avoid referencing them, we copy them, but only once).
106
    assignments: RefMap<Assignment>,
107
    /// storage for all source paths we have matched so far (in order to avoid referencing them, we copy them, but only once).
108
    source_paths: RefMap<std::path::PathBuf>,
109
    /// The amount of attributes that still need to be set, or `None` if this outcome is consumed which means it
110
    /// needs to be re-initialized.
111
    remaining: Option<usize>,
112
}
113
114
#[derive(Default, Clone)]
115
struct Slot {
116
    r#match: Option<outcome::Match>,
117
    /// A list of all assignments, being an empty list for non-macro attributes, or all assignments (with order) for macros.
118
    /// It's used to resolve macros.
119
    macro_attributes: Assignments,
120
}
121
122
/// A type to denote an id of an attribute assignment for uniquely identifying each attribute or assignment.
123
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
124
pub struct AttributeId(pub usize);
125
126
impl Default for AttributeId {
127
18.0k
    fn default() -> Self {
128
18.0k
        AttributeId(usize::MAX)
129
18.0k
    }
Unexecuted instantiation: <gix_attributes::search::AttributeId as core::default::Default>::default
<gix_attributes::search::AttributeId as core::default::Default>::default
Line
Count
Source
127
18.0k
    fn default() -> Self {
128
18.0k
        AttributeId(usize::MAX)
129
18.0k
    }
130
}
131
132
/// A utility type to collect metadata for each attribute, unified by its name.
133
#[derive(Clone, Debug, Default)]
134
pub struct MetadataCollection {
135
    /// A mapping of an attribute or macro name to its order, that is the time when it was *first* seen.
136
    ///
137
    /// This is the inverse of the order attributes are searched.
138
    name_to_meta: HashMap<Name, Metadata>,
139
}
140
141
/// Metadata associated with an attribute or macro name.
142
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
143
pub struct Metadata {
144
    /// The id to uniquely identify an attribute in the [MetadataCollection].
145
    pub id: AttributeId,
146
    /// If non-zero in length, this entry belongs to a macro which resolves to these attribute names.
147
    pub macro_attributes: Assignments,
148
}
149
150
const AVERAGE_NUM_ATTRS: usize = 3;