1use crate::*;
2
3#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
4pub struct Range {
5 pub comparator_set: Vec<Comparator>,
6 pub compat: range_set::Compat,
7}
8
9#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
10pub struct Comparator {
11 pub op: Op,
12 pub major: u64,
13 pub minor: u64,
14 pub patch: u64,
15 pub pre: Vec<Identifier>,
16}
17
18#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
19pub enum Op {
20 Lt,
21 Lte,
22 Gt,
23 Gte,
24 Eq,
25}
26
27#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
28pub enum Identifier {
29 Numeric(u64),
30 AlphaNumeric(String),
31}
32
33#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
34pub struct Partial {
35 major: Option<u64>,
36 minor: Option<u64>,
37 patch: Option<u64>,
38 pre: Vec<Identifier>,
39 kind: PartialKind,
40}
41
42#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
43pub enum PartialKind {
44 XRangeOnly,
45 MajorOnly,
46 MajorMinor,
47 MajorMinorPatch,
48}
49
50impl Partial {
51 pub fn new() -> Self {
52 Self {
53 major: None,
54 minor: None,
55 patch: None,
56 pre: Vec::new(),
57 kind: PartialKind::XRangeOnly,
58 }
59 }
60
61 pub fn as_comparator(&self, op: Op) -> Comparator {
62 Comparator {
63 op,
64 major: self.major.unwrap_or(0),
65 minor: self.minor.unwrap_or(0),
66 patch: self.patch.unwrap_or(0),
67 pre: self.pre.clone(),
68 }
69 }
70
71 pub fn inc_major(&mut self) -> &mut Self {
72 self.major = Some(self.major.unwrap_or(0) + 1);
73 self
74 }
75
76 pub fn inc_minor(&mut self) -> &mut Self {
77 self.minor = Some(self.minor.unwrap_or(0) + 1);
78 self
79 }
80
81 pub fn inc_patch(&mut self) -> &mut Self {
82 self.patch = Some(self.patch.unwrap_or(0) + 1);
83 self
84 }
85
86 pub fn zero_missing(&mut self) -> &mut Self {
87 self.major = Some(self.major.unwrap_or(0));
88 self.minor = Some(self.minor.unwrap_or(0));
89 self.patch = Some(self.patch.unwrap_or(0));
90 self
91 }
92
93 pub fn zero_minor(&mut self) -> &mut Self {
94 self.minor = Some(0);
95 self
96 }
97
98 pub fn zero_patch(&mut self) -> &mut Self {
99 self.patch = Some(0);
100 self
101 }
102
103 pub fn no_pre(&mut self) -> &mut Self {
104 self.pre = Vec::new();
105 self
106 }
107}
108
109pub fn from_pair_iterator(
110 parsed_range: pest::iterators::Pair<'_, Rule>,
111 compat: range_set::Compat,
112) -> Result<Range, String> {
113 if parsed_range.as_rule() != Rule::range {
115 return Err(String::from("Error parsing range"));
116 }
117
118 let mut comparator_set = Vec::new();
119
120 for record in parsed_range.into_inner() {
122 match record.as_rule() {
123 Rule::hyphen => {
124 let mut hyphen_set = simple::from_hyphen_range(record)?;
125 comparator_set.append(&mut hyphen_set);
126 }
127 Rule::simple => {
128 let mut comparators = simple::from_pair_iterator(record, compat)?;
129 comparator_set.append(&mut comparators);
130 }
131 Rule::empty => {
132 comparator_set.push(Partial::new().zero_missing().as_comparator(Op::Gte));
133 }
134 _ => unreachable!(),
135 }
136 }
137
138 Ok(Range {
139 comparator_set,
140 compat,
141 })
142}
143
144pub mod simple {
145 use super::*;
146
147 pub fn from_pair_iterator(
148 parsed_simple: pest::iterators::Pair<'_, Rule>,
149 compat: range_set::Compat,
150 ) -> Result<Vec<Comparator>, String> {
151 if parsed_simple.as_rule() != Rule::simple {
153 return Err(String::from("Error parsing comparator set"));
154 }
155
156 let mut comparators = Vec::new();
157
158 for record in parsed_simple.into_inner() {
160 match record.as_rule() {
161 Rule::partial => {
162 let components: Vec<_> = record.into_inner().collect();
163
164 let mut partial = parse_partial(components);
165
166 match partial.kind {
167 PartialKind::XRangeOnly => {
168 comparators.push(partial.zero_missing().as_comparator(Op::Gte));
170 }
171 PartialKind::MajorOnly => {
172 comparators.push(partial.clone().zero_missing().as_comparator(Op::Gte));
175 comparators
176 .push(partial.inc_major().zero_missing().as_comparator(Op::Lt));
177 }
178 PartialKind::MajorMinor => {
179 comparators.push(partial.clone().zero_patch().as_comparator(Op::Gte));
181 comparators
182 .push(partial.inc_minor().zero_patch().as_comparator(Op::Lt));
183 }
184 PartialKind::MajorMinorPatch => {
185 match compat {
186 range_set::Compat::Npm => {
187 comparators.push(partial.as_comparator(Op::Eq));
189 }
190 range_set::Compat::Cargo => {
191 handle_caret_range(partial, &mut comparators);
193 }
194 }
195 }
196 }
197 }
198 Rule::primitive => {
199 let mut components: Vec<_> = record.into_inner().collect();
200 let op_component = components.remove(0);
201
202 let op = match op_component.as_str() {
203 "=" => Op::Eq,
204 "<" => Op::Lt,
205 "<=" => Op::Lte,
206 ">" => Op::Gt,
207 ">=" => Op::Gte,
208 _ => unreachable!(),
209 };
210
211 let partial_component = components.remove(0);
212 let components: Vec<_> = partial_component.into_inner().collect();
213 let mut partial = parse_partial(components);
214
215 if op == Op::Eq {
217 match partial.kind {
218 PartialKind::XRangeOnly => {
219 comparators.push(partial.zero_missing().as_comparator(Op::Gte));
221 }
222 PartialKind::MajorOnly => {
223 comparators
225 .push(partial.clone().zero_missing().as_comparator(Op::Gte));
226 comparators
227 .push(partial.inc_major().zero_missing().as_comparator(Op::Lt));
228 }
229 PartialKind::MajorMinor => {
230 comparators
232 .push(partial.clone().zero_patch().as_comparator(Op::Gte));
233 comparators
234 .push(partial.inc_minor().zero_patch().as_comparator(Op::Lt));
235 }
236 PartialKind::MajorMinorPatch => {
237 comparators.push(partial.as_comparator(Op::Eq));
238 }
239 }
240 } else {
241 match partial.kind {
242 PartialKind::XRangeOnly => {
243 match op {
244 Op::Eq => comparators
245 .push(partial.zero_missing().as_comparator(Op::Gte)),
246 Op::Lt => comparators
247 .push(partial.zero_missing().as_comparator(Op::Lt)),
248 Op::Lte => comparators
249 .push(partial.zero_missing().as_comparator(Op::Gte)),
250 Op::Gt => comparators
251 .push(partial.zero_missing().as_comparator(Op::Lt)),
252 Op::Gte => comparators
253 .push(partial.zero_missing().as_comparator(Op::Gte)),
254 }
255 }
256 PartialKind::MajorOnly => {
257 match op {
260 Op::Lte => comparators.push(
261 partial
262 .inc_major()
263 .zero_minor()
264 .zero_patch()
265 .as_comparator(Op::Lt),
266 ),
267 _ => comparators.push(partial.zero_missing().as_comparator(op)),
268 }
269 }
270 PartialKind::MajorMinor => {
271 match op {
273 Op::Lte => comparators.push(
274 partial.inc_minor().zero_patch().as_comparator(Op::Lt),
275 ),
276 _ => comparators.push(partial.zero_patch().as_comparator(op)),
277 }
278 }
279 PartialKind::MajorMinorPatch => {
280 comparators.push(partial.as_comparator(op));
281 }
282 }
283 }
284 }
285 Rule::caret => {
286 let mut components: Vec<_> = record.into_inner().collect();
287
288 let partial_component = components.remove(0);
289 let components: Vec<_> = partial_component.into_inner().collect();
290 let partial = parse_partial(components);
291
292 handle_caret_range(partial, &mut comparators);
293 }
294 Rule::tilde => {
295 let mut components: Vec<_> = record.into_inner().collect();
296
297 let partial_component = components.remove(0);
298 let components: Vec<_> = partial_component.into_inner().collect();
299 let mut partial = parse_partial(components);
300
301 comparators.push(partial.clone().zero_missing().as_comparator(Op::Gte));
302
303 match partial.kind {
304 PartialKind::XRangeOnly => {
305 }
308 PartialKind::MajorOnly => {
309 comparators.push(
311 partial
312 .inc_major()
313 .zero_missing()
314 .no_pre()
315 .as_comparator(Op::Lt),
316 );
317 }
318 PartialKind::MajorMinor | PartialKind::MajorMinorPatch => {
319 comparators.push(
322 partial
323 .inc_minor()
324 .zero_patch()
325 .no_pre()
326 .as_comparator(Op::Lt),
327 );
328 }
329 }
330 }
331 _ => unreachable!(),
332 }
333 }
334
335 Ok(comparators)
336 }
337
338 fn handle_caret_range(mut partial: Partial, comparators: &mut Vec<Comparator>) {
339 if partial.major == Some(0) {
341 match partial.kind {
342 PartialKind::XRangeOnly => unreachable!(),
343 PartialKind::MajorOnly => {
344 comparators.push(partial.clone().zero_missing().as_comparator(Op::Gte));
346 comparators.push(
347 partial
348 .inc_major()
349 .zero_missing()
350 .no_pre()
351 .as_comparator(Op::Lt),
352 );
353 }
354 PartialKind::MajorMinor => {
355 comparators.push(partial.clone().zero_missing().as_comparator(Op::Gte));
357 comparators.push(
358 partial
359 .inc_minor()
360 .zero_patch()
361 .no_pre()
362 .as_comparator(Op::Lt),
363 );
364 }
365 PartialKind::MajorMinorPatch => {
366 if partial.minor == Some(0) {
367 comparators.push(partial.as_comparator(Op::Gte));
369 comparators.push(partial.inc_patch().no_pre().as_comparator(Op::Lt));
370 } else {
371 comparators.push(partial.as_comparator(Op::Gte));
373 comparators.push(
374 partial
375 .inc_minor()
376 .zero_patch()
377 .no_pre()
378 .as_comparator(Op::Lt),
379 );
380 }
381 }
382 }
383 } else {
384 match partial.kind {
385 PartialKind::XRangeOnly => {
386 comparators.push(partial.zero_missing().as_comparator(Op::Gte));
388 }
389 _ => {
390 comparators.push(partial.clone().zero_missing().as_comparator(Op::Gte));
394 comparators.push(
395 partial
396 .inc_major()
397 .zero_minor()
398 .zero_patch()
399 .no_pre()
400 .as_comparator(Op::Lt),
401 );
402 }
403 }
404 }
405 }
406
407 pub fn from_hyphen_range(
408 parsed_simple: pest::iterators::Pair<'_, Rule>,
409 ) -> Result<Vec<Comparator>, String> {
410 if parsed_simple.as_rule() != Rule::hyphen {
412 return Err(String::from("Error parsing comparator set"));
413 }
414
415 let mut comparators = Vec::new();
416
417 let mut records = parsed_simple.into_inner();
419
420 let components1: Vec<_> = records.next().unwrap().into_inner().collect();
421 let mut partial1 = parse_partial(components1);
422 match partial1.kind {
423 PartialKind::XRangeOnly => {
424 }
427 _ => comparators.push(partial1.zero_missing().as_comparator(Op::Gte)),
428 }
429
430 let components2: Vec<_> = records.next().unwrap().into_inner().collect();
431 let mut partial2 = parse_partial(components2);
432
433 match partial2.kind {
434 PartialKind::XRangeOnly => {
435 if partial1.kind == PartialKind::XRangeOnly {
437 comparators.push(partial2.zero_missing().as_comparator(Op::Gte));
438 }
439 }
440 PartialKind::MajorOnly => {
441 comparators.push(
443 partial2
444 .inc_major()
445 .zero_minor()
446 .zero_patch()
447 .as_comparator(Op::Lt),
448 );
449 }
450 PartialKind::MajorMinor => {
451 comparators.push(partial2.inc_minor().zero_patch().as_comparator(Op::Lt));
453 }
454 PartialKind::MajorMinorPatch => {
455 comparators.push(partial2.as_comparator(Op::Lte));
457 }
458 }
459
460 Ok(comparators)
461 }
462
463 fn parse_partial(mut components: Vec<pest::iterators::Pair<'_, Rule>>) -> Partial {
464 let mut partial = Partial::new();
465
466 let one = components.remove(0);
468
469 match one.as_rule() {
470 Rule::xr => {
471 let inner = one.into_inner().next().unwrap();
472 match inner.as_rule() {
473 Rule::xr_op => {
474 partial.major = None;
476 partial.kind = PartialKind::XRangeOnly;
477 return partial;
479 }
480 Rule::nr => {
481 partial.major = Some(inner.as_str().parse::<u64>().unwrap());
482 }
483 _ => unreachable!(),
484 }
485 }
486 _ => unreachable!(),
487 }
488
489 if components.is_empty() {
490 partial.kind = PartialKind::MajorOnly;
492 return partial;
493 } else {
494 let two = components.remove(0);
495
496 match two.as_rule() {
497 Rule::xr => {
498 let inner = two.into_inner().next().unwrap();
499 match inner.as_rule() {
500 Rule::xr_op => {
501 partial.minor = None;
502 partial.kind = PartialKind::MajorOnly;
504 return partial;
505 }
506 Rule::nr => {
507 partial.minor = Some(inner.as_str().parse::<u64>().unwrap());
508 }
509 _ => unreachable!(),
510 }
511 }
512 _ => unreachable!(),
513 }
514 }
515
516 if components.is_empty() {
517 partial.kind = PartialKind::MajorMinor;
519 return partial;
520 } else {
521 let three = components.remove(0);
522
523 match three.as_rule() {
524 Rule::xr => {
525 let inner = three.into_inner().next().unwrap();
526 match inner.as_rule() {
527 Rule::xr_op => {
528 partial.patch = None;
529 partial.kind = PartialKind::MajorMinor;
531 return partial;
532 }
533 Rule::nr => {
534 partial.patch = Some(inner.as_str().parse::<u64>().unwrap());
535 }
536 _ => unreachable!(),
537 }
538 }
539 _ => unreachable!(),
540 }
541 }
542
543 partial.kind = PartialKind::MajorMinorPatch;
545
546 if !components.is_empty() {
547 let pre = components.remove(0);
549 let mut pre: Vec<_> = pre.into_inner().collect();
551 let pre = pre.remove(0);
552 let pre = pre.as_str();
553
554 for bit in pre.split('.') {
556 let identifier = match bit.parse::<u64>() {
557 Ok(num) => Identifier::Numeric(num),
558 Err(_) => Identifier::AlphaNumeric(bit.to_string()),
559 };
560
561 partial.pre.push(identifier);
562 }
563 }
564
565 partial
566 }
567}
568
569#[cfg(test)]
570mod tests {
571 use super::*;
572 use pest::Parser;
573
574 fn parse_range(input: &str) -> pest::iterators::Pair<'_, Rule> {
575 match SemverParser::parse(Rule::range, input) {
576 Ok(mut parsed) => match parsed.next() {
577 Some(parsed) => parsed,
578 None => panic!("Could not parse {}", input),
579 },
580 Err(e) => panic!("Parse error:\n{}", e),
581 }
582 }
583
584 macro_rules! range_tests {
587 ( $( $name:ident: $value:expr, )* ) => {
588 $(
589 #[test]
590 fn $name() {
591 let (input, expected_range) = $value;
592
593 let parsed_range = parse_range(input);
594 let range = from_pair_iterator(parsed_range, range_set::Compat::Cargo).expect("parsing failed");
595
596 let num_comparators = range.comparator_set.len();
598 let expected_comparators = expected_range.comparator_set.len();
599 assert_eq!(expected_comparators, num_comparators, "expected number of comparators: {}, got: {}", expected_comparators, num_comparators);
600
601 assert_eq!(range, expected_range);
602 }
603 )*
604 };
605 }
606
607 macro_rules! range_tests_nodecompat {
608 ( $( $name:ident: $value:expr, )* ) => {
609 $(
610 #[test]
611 fn $name() {
612 let (input, expected_range) = $value;
613
614 let parsed_range = parse_range(input);
615 let range = from_pair_iterator(parsed_range, range_set::Compat::Npm).expect("parsing failed");
616
617 let num_comparators = range.comparator_set.len();
619 let expected_comparators = expected_range.comparator_set.len();
620 assert_eq!(expected_comparators, num_comparators, "expected number of comparators: {}, got: {}", expected_comparators, num_comparators);
621
622 assert_eq!(range, expected_range);
623 }
624 )*
625 };
626 }
627
628 macro_rules! comp_sets {
629 ( $( [$op:expr, $major:expr, $minor:expr, $patch:expr] ),* ) => {
630 Range {
631 comparator_set: vec![
632 $(
633 Comparator {
634 op: $op,
635 major: $major,
636 minor: $minor,
637 patch: $patch,
638 pre: pre!(None),
639 },
640 )*
641 ],
642 compat: range_set::Compat::Cargo
643 }
644 };
645 ( $( [$op:expr, $major:expr, $minor:expr, $patch:expr, $pre:expr] ),* ) => {
647 Range {
648 comparator_set: vec![
649 $(
650 Comparator {
651 op: $op,
652 major: $major,
653 minor: $minor,
654 patch: $patch,
655 pre: $pre,
656 },
657 )*
658 ],
659 compat: range_set::Compat::Cargo
660 }
661 };
662 }
663
664 macro_rules! comp_sets_node {
666 ( $( [$op:expr, $major:expr, $minor:expr, $patch:expr] ),* ) => {
667 Range {
668 comparator_set: vec![
669 $(
670 Comparator {
671 op: $op,
672 major: $major,
673 minor: $minor,
674 patch: $patch,
675 pre: pre!(None),
676 },
677 )*
678 ],
679 compat: range_set::Compat::Npm
680 }
681 };
682 }
683
684 macro_rules! id_num {
685 ( $num:expr ) => {
686 Identifier::Numeric($num)
687 };
688 }
689
690 macro_rules! id_alpha {
691 ( $alpha:expr ) => {
692 Identifier::AlphaNumeric(String::from($alpha))
693 };
694 }
695
696 macro_rules! pre {
697 ( None ) => {
698 Vec::new()
699 };
700 ( $( $e:expr ),* ) => {
701 vec![
702 $(
703 $e,
704 )*
705 ]
706 };
707 }
708
709 macro_rules! op {
710 ( "=" ) => {
711 Op::Eq
712 };
713 ( "<" ) => {
714 Op::Lt
715 };
716 ( "<=" ) => {
717 Op::Lte
718 };
719 ( ">" ) => {
720 Op::Gt
721 };
722 ( ">=" ) => {
723 Op::Gte
724 };
725 }
726
727 range_tests! {
730 major: ("1", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
731 major_minor: ("1.2", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 1, 3, 0] )),
732 major_minor_patch: ("1.2.3", comp_sets!( [op!(">="), 1, 2, 3], [op!("<"), 2, 0, 0] )),
733 major_0_minor_patch: ("0.2.3", comp_sets!( [op!(">="), 0, 2, 3], [op!("<"), 0, 3, 0] )),
734 major_0_minor_0_patch: ("0.0.1", comp_sets!( [op!(">="), 0, 0, 1], [op!("<"), 0, 0, 2] )),
735
736 eq_major: ("=1", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
737 eq_major_minor: ("=1.2", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 1, 3, 0] )),
738 eq_major_minor_patch: ("=1.2.3", comp_sets!( [op!("="), 1, 2, 3] )),
739 eq_all: ("=*", comp_sets!( [op!(">="), 0, 0, 0] )),
740 eq_major_star: ("=1.*", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
741 eq_major_minor_star: ("=1.2.*", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 1, 3, 0] )),
742
743 lt_major: ("<1", comp_sets!( [op!("<"), 1, 0, 0] )),
744 lt_major_minor: ("<1.2", comp_sets!( [op!("<"), 1, 2, 0] )),
745 lt_major_minor_patch: ("<1.2.3", comp_sets!( [op!("<"), 1, 2, 3] )),
746 lt_all: ("<*", comp_sets!( [op!("<"), 0, 0, 0] )),
747 lt_major_star: ("<1.*", comp_sets!( [op!("<"), 1, 0, 0] )),
748 lt_major_minor_star: ("<1.2.*", comp_sets!( [op!("<"), 1, 2, 0] )),
749
750 lte_major: ("<=1", comp_sets!( [op!("<"), 2, 0, 0] )),
751 lte_major_minor: ("<=1.2", comp_sets!( [op!("<"), 1, 3, 0] )),
752 lte_major_minor_patch: ("<=1.2.3", comp_sets!( [op!("<="), 1, 2, 3] )),
753 lte_all: ("<=*", comp_sets!( [op!(">="), 0, 0, 0] )),
754 lte_major_star: ("<=1.*", comp_sets!( [op!("<"), 2, 0, 0] )),
755 lte_major_minor_star: ("<=1.2.*", comp_sets!( [op!("<"), 1, 3, 0] )),
756
757 gt_major: (">1", comp_sets!( [op!(">"), 1, 0, 0] )),
758 gt_major_minor: (">1.2", comp_sets!( [op!(">"), 1, 2, 0] )),
759 gt_major_minor_patch: (">1.2.3", comp_sets!( [op!(">"), 1, 2, 3] )),
760 gt_all: (">*", comp_sets!( [op!("<"), 0, 0, 0] )),
761 gt_major_star: (">1.*", comp_sets!( [op!(">"), 1, 0, 0] )),
762 gt_major_minor_star: (">1.2.*", comp_sets!( [op!(">"), 1, 2, 0] )),
763
764 gte_major: (">=1", comp_sets!( [op!(">="), 1, 0, 0] )),
765 gte_major_minor: (">=1.2", comp_sets!( [op!(">="), 1, 2, 0] )),
766 gte_major_minor_patch: (">=1.2.3", comp_sets!( [op!(">="), 1, 2, 3] )),
767 gte_all: (">=*", comp_sets!( [op!(">="), 0, 0, 0] )),
768 gte_major_star: (">=1.*", comp_sets!( [op!(">="), 1, 0, 0] )),
769 gte_major_minor_star: (">=1.2.*", comp_sets!( [op!(">="), 1, 2, 0] )),
770
771 tilde_major: ("~1", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
772 tilde_major_0: ("~0", comp_sets!( [op!(">="), 0, 0, 0], [op!("<"), 1, 0, 0] )),
773 tilde_major_xrange: ("~1.x", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
774 tilde_major_2: ("~>1", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
775 tilde_major_minor: ("~1.2", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 1, 3, 0] )),
776 tilde_major_minor_xrange: ("~1.2.x", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 1, 3, 0] )),
777 tilde_major_minor_2: ("~>1.2", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 1, 3, 0] )),
778 tilde_major_minor_patch: ("~1.2.3", comp_sets!( [op!(">="), 1, 2, 3], [op!("<"), 1, 3, 0] )),
779 tilde_major_minor_patch_pre: ("~1.2.3-beta", comp_sets!( [op!(">="), 1, 2, 3, pre!(id_alpha!("beta"))], [op!("<"), 1, 3, 0, pre!()] )),
780 tilde_major_minor_patch_2: ("~>1.2.3", comp_sets!( [op!(">="), 1, 2, 3], [op!("<"), 1, 3, 0] )),
781 tilde_major_0_minor_patch: ("~0.2.3", comp_sets!( [op!(">="), 0, 2, 3], [op!("<"), 0, 3, 0] )),
782 tilde_all: ("~*", comp_sets!( [op!(">="), 0, 0, 0] )),
783
784 caret_major: ("^1", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
785 caret_major_xrange: ("^1.x", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
786 caret_major_minor: ("^1.2", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 2, 0, 0] )),
787 caret_major_minor_xrange: ("^1.2.x", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 2, 0, 0] )),
788 caret_major_minor_patch: ("^1.2.3", comp_sets!( [op!(">="), 1, 2, 3], [op!("<"), 2, 0, 0] )),
789 caret_major_minor_patch_pre: ("^1.2.3-beta.4", comp_sets!( [op!(">="), 1, 2, 3, pre!(id_alpha!("beta"), id_num!(4))], [op!("<"), 2, 0, 0, pre!()] )),
790
791 caret_major_0: ("^0", comp_sets!( [op!(">="), 0, 0, 0], [op!("<"), 1, 0, 0] )),
792 caret_major_0_xrange: ("^0.x", comp_sets!( [op!(">="), 0, 0, 0], [op!("<"), 1, 0, 0] )),
793 caret_major_0_minor_0: ("^0.0", comp_sets!( [op!(">="), 0, 0, 0], [op!("<"), 0, 1, 0] )),
794 caret_major_0_minor_0_xrange: ("^0.0.x", comp_sets!( [op!(">="), 0, 0, 0], [op!("<"), 0, 1, 0] )),
795 caret_major_0_minor: ("^0.1", comp_sets!( [op!(">="), 0, 1, 0], [op!("<"), 0, 2, 0] )),
796 caret_major_0_minor_xrange: ("^0.1.x", comp_sets!( [op!(">="), 0, 1, 0], [op!("<"), 0, 2, 0] )),
797 caret_major_0_minor_patch: ("^0.1.2", comp_sets!( [op!(">="), 0, 1, 2], [op!("<"), 0, 2, 0] )),
798 caret_major_0_minor_0_patch: ("^0.0.1", comp_sets!( [op!(">="), 0, 0, 1], [op!("<"), 0, 0, 2] )),
799 caret_major_0_minor_0_pre: ("^0.0.1-beta", comp_sets!( [op!(">="), 0, 0, 1, pre!(id_alpha!("beta"))], [op!("<"), 0, 0, 2, pre!()] )),
800 caret_all: ("^*", comp_sets!( [op!(">="), 0, 0, 0] )),
801
802 two_comparators_1: (">1.2.3 <4.5.6", comp_sets!( [op!(">"), 1, 2, 3], [op!("<"), 4, 5, 6] )),
803 two_comparators_2: ("^1.2 ^1", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 2, 0, 0], [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
804
805 comparator_with_pre: ("=1.2.3-rc.1", comp_sets!( [op!("="), 1, 2, 3, pre!(id_alpha!("rc"), id_num!(1))] )),
806
807 hyphen_major: ("1 - 4", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 5, 0, 0] )),
808 hyphen_major_x: ("1.* - 4.*", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 5, 0, 0] )),
809 hyphen_major_minor_x: ("1.2.x - 4.5.x", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 4, 6, 0] )),
810 hyphen_major_minor_patch: ("1.2.3 - 4.5.6", comp_sets!( [op!(">="), 1, 2, 3], [op!("<="), 4, 5, 6] )),
811 hyphen_with_pre: ("1.2.3-rc1 - 4.5.6", comp_sets!( [op!(">="), 1, 2, 3, pre!(id_alpha!("rc1"))], [op!("<="), 4, 5, 6, pre!()] )),
812 hyphen_xrange_minor_only1: ("1.*.3 - 3.4.5", comp_sets!( [op!(">="), 1, 0, 0], [op!("<="), 3, 4, 5] )),
813 hyphen_xrange_minor_only2: ("1.2.3 - 3.*.5", comp_sets!( [op!(">="), 1, 2, 3], [op!("<"), 4, 0, 0] )),
814
815 hyphen_all_to_something: ("* - 3.4.5", comp_sets!( [op!("<="), 3, 4, 5] )),
816 hyphen_to_all: ("1.2.3 - *", comp_sets!( [op!(">="), 1, 2, 3] )),
817 hyphen_all_to_all: ("* - *", comp_sets!( [op!(">="), 0, 0, 0] )),
818
819 gte_space: (">= 1.2.3", comp_sets!( [op!(">="), 1, 2, 3] )),
820 gte_tab: (">=\t1.2.3", comp_sets!( [op!(">="), 1, 2, 3] )),
821 gte_two_spaces: (">= 1.2.3", comp_sets!( [op!(">="), 1, 2, 3] )),
822 gt_space: ("> 1.2.3", comp_sets!( [op!(">"), 1, 2, 3] )),
823 gt_two_spaces: ("> 1.2.3", comp_sets!( [op!(">"), 1, 2, 3] )),
824 lte_space: ("<= 1.2.3", comp_sets!( [op!("<="), 1, 2, 3] )),
825 lte_two_spaces: ("<= 1.2.3", comp_sets!( [op!("<="), 1, 2, 3] )),
826 lt_space: ("< 1.2.3", comp_sets!( [op!("<"), 1, 2, 3] )),
827 lt_two_spaces: ("< 1.2.3", comp_sets!( [op!("<"), 1, 2, 3] )),
828 eq_space: ("= 1.2.3", comp_sets!( [op!("="), 1, 2, 3] )),
829 eq_two_spaces: ("= 1.2.3", comp_sets!( [op!("="), 1, 2, 3] )),
830 caret_space: ("^ 1.2.3", comp_sets!( [op!(">="), 1, 2, 3], [op!("<"), 2, 0, 0] )),
831 tilde_space: ("~ 1.2.3", comp_sets!( [op!(">="), 1, 2, 3], [op!("<"), 1, 3, 0] )),
832 hyphen_spacing: ("1.2.3 - 4.5.6", comp_sets!( [op!(">="), 1, 2, 3], [op!("<="), 4, 5, 6] )),
833
834 digits: ("=0.2.3", comp_sets!( [op!("="), 0, 2, 3] )),
836 digits_2: ("=11.2.3", comp_sets!( [op!("="), 11, 2, 3] )),
837 digits_3: ("=1.12.3", comp_sets!( [op!("="), 1, 12, 3] )),
838 digits_4: ("=1.2.13", comp_sets!( [op!("="), 1, 2, 13] )),
839 digits_5: ("=1.2.5678", comp_sets!( [op!("="), 1, 2, 5678] )),
840
841 xrange_major_x: ("1.x", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
842 xrange_major_x_x: ("1.x.x", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
843 xrange_major_minor_x: ("1.2.x", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 1, 3, 0] )),
844 xrange_major_xx: ("1.X", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
845 xrange_major_xx_xx: ("1.X.X", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
846 xrange_major_minor_xx: ("1.2.X", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 1, 3, 0] )),
847 xrange_star: ("*", comp_sets!( [op!(">="), 0, 0, 0] )),
848 xrange_x: ("x", comp_sets!( [op!(">="), 0, 0, 0] )),
849 xrange_xx: ("X", comp_sets!( [op!(">="), 0, 0, 0] )),
850 xrange_major_star: ("1.*", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
851 xrange_major_star_star: ("1.*.*", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
852 xrange_major_minor_star: ("1.2.*", comp_sets!( [op!(">="), 1, 2, 0], [op!("<"), 1, 3, 0] )),
853 xrange_with_pre: ("1.*.*-beta", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
854 xrange_minor_only: ("1.*.3", comp_sets!( [op!(">="), 1, 0, 0], [op!("<"), 2, 0, 0] )),
856
857 gte_star: (">=*", comp_sets!( [op!(">="), 0, 0, 0] )),
859 empty: ("", comp_sets!( [op!(">="), 0, 0, 0] )),
860 }
861
862 range_tests_nodecompat! {
863 node_major_minor_patch: ("1.2.3", comp_sets_node!( [op!("="), 1, 2, 3] )),
864 }
865}