/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 | } |