Coverage Report

Created: 2025-11-28 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/semver-1.0.27/src/eval.rs
Line
Count
Source
1
use crate::{Comparator, Op, Version, VersionReq};
2
3
0
pub(crate) fn matches_req(req: &VersionReq, ver: &Version) -> bool {
4
0
    for cmp in &req.comparators {
5
0
        if !matches_impl(cmp, ver) {
6
0
            return false;
7
0
        }
8
    }
9
10
0
    if ver.pre.is_empty() {
11
0
        return true;
12
0
    }
13
14
    // If a version has a prerelease tag (for example, 1.2.3-alpha.3) then it
15
    // will only be allowed to satisfy req if at least one comparator with the
16
    // same major.minor.patch also has a prerelease tag.
17
0
    for cmp in &req.comparators {
18
0
        if pre_is_compatible(cmp, ver) {
19
0
            return true;
20
0
        }
21
    }
22
23
0
    false
24
0
}
25
26
0
pub(crate) fn matches_comparator(cmp: &Comparator, ver: &Version) -> bool {
27
0
    matches_impl(cmp, ver) && (ver.pre.is_empty() || pre_is_compatible(cmp, ver))
28
0
}
29
30
0
fn matches_impl(cmp: &Comparator, ver: &Version) -> bool {
31
0
    match cmp.op {
32
0
        Op::Exact | Op::Wildcard => matches_exact(cmp, ver),
33
0
        Op::Greater => matches_greater(cmp, ver),
34
0
        Op::GreaterEq => matches_exact(cmp, ver) || matches_greater(cmp, ver),
35
0
        Op::Less => matches_less(cmp, ver),
36
0
        Op::LessEq => matches_exact(cmp, ver) || matches_less(cmp, ver),
37
0
        Op::Tilde => matches_tilde(cmp, ver),
38
0
        Op::Caret => matches_caret(cmp, ver),
39
    }
40
0
}
41
42
0
fn matches_exact(cmp: &Comparator, ver: &Version) -> bool {
43
0
    if ver.major != cmp.major {
44
0
        return false;
45
0
    }
46
47
0
    if let Some(minor) = cmp.minor {
48
0
        if ver.minor != minor {
49
0
            return false;
50
0
        }
51
0
    }
52
53
0
    if let Some(patch) = cmp.patch {
54
0
        if ver.patch != patch {
55
0
            return false;
56
0
        }
57
0
    }
58
59
0
    ver.pre == cmp.pre
60
0
}
61
62
0
fn matches_greater(cmp: &Comparator, ver: &Version) -> bool {
63
0
    if ver.major != cmp.major {
64
0
        return ver.major > cmp.major;
65
0
    }
66
67
0
    match cmp.minor {
68
0
        None => return false,
69
0
        Some(minor) => {
70
0
            if ver.minor != minor {
71
0
                return ver.minor > minor;
72
0
            }
73
        }
74
    }
75
76
0
    match cmp.patch {
77
0
        None => return false,
78
0
        Some(patch) => {
79
0
            if ver.patch != patch {
80
0
                return ver.patch > patch;
81
0
            }
82
        }
83
    }
84
85
0
    ver.pre > cmp.pre
86
0
}
87
88
0
fn matches_less(cmp: &Comparator, ver: &Version) -> bool {
89
0
    if ver.major != cmp.major {
90
0
        return ver.major < cmp.major;
91
0
    }
92
93
0
    match cmp.minor {
94
0
        None => return false,
95
0
        Some(minor) => {
96
0
            if ver.minor != minor {
97
0
                return ver.minor < minor;
98
0
            }
99
        }
100
    }
101
102
0
    match cmp.patch {
103
0
        None => return false,
104
0
        Some(patch) => {
105
0
            if ver.patch != patch {
106
0
                return ver.patch < patch;
107
0
            }
108
        }
109
    }
110
111
0
    ver.pre < cmp.pre
112
0
}
113
114
0
fn matches_tilde(cmp: &Comparator, ver: &Version) -> bool {
115
0
    if ver.major != cmp.major {
116
0
        return false;
117
0
    }
118
119
0
    if let Some(minor) = cmp.minor {
120
0
        if ver.minor != minor {
121
0
            return false;
122
0
        }
123
0
    }
124
125
0
    if let Some(patch) = cmp.patch {
126
0
        if ver.patch != patch {
127
0
            return ver.patch > patch;
128
0
        }
129
0
    }
130
131
0
    ver.pre >= cmp.pre
132
0
}
133
134
0
fn matches_caret(cmp: &Comparator, ver: &Version) -> bool {
135
0
    if ver.major != cmp.major {
136
0
        return false;
137
0
    }
138
139
0
    let minor = match cmp.minor {
140
0
        None => return true,
141
0
        Some(minor) => minor,
142
    };
143
144
0
    let patch = match cmp.patch {
145
        None => {
146
0
            if cmp.major > 0 {
147
0
                return ver.minor >= minor;
148
            } else {
149
0
                return ver.minor == minor;
150
            }
151
        }
152
0
        Some(patch) => patch,
153
    };
154
155
0
    if cmp.major > 0 {
156
0
        if ver.minor != minor {
157
0
            return ver.minor > minor;
158
0
        } else if ver.patch != patch {
159
0
            return ver.patch > patch;
160
0
        }
161
0
    } else if minor > 0 {
162
0
        if ver.minor != minor {
163
0
            return false;
164
0
        } else if ver.patch != patch {
165
0
            return ver.patch > patch;
166
0
        }
167
0
    } else if ver.minor != minor || ver.patch != patch {
168
0
        return false;
169
0
    }
170
171
0
    ver.pre >= cmp.pre
172
0
}
173
174
0
fn pre_is_compatible(cmp: &Comparator, ver: &Version) -> bool {
175
0
    cmp.major == ver.major
176
0
        && cmp.minor == Some(ver.minor)
177
0
        && cmp.patch == Some(ver.patch)
178
0
        && !cmp.pre.is_empty()
179
0
}