1use std::collections::BTreeSet;
13use std::fmt;
14use thiserror::Error;
15
16pub const AUTOSTEP_DISABLED: f64 = 1e100;
18
19#[derive(Debug, Error)]
24pub enum RangeSetError {
25 #[error("parse error: {msg} (in \"{part}\")")]
26 ParseError { part: String, msg: String },
27
28 #[error("padding mismatch: {msg} (in \"{part}\")")]
29 PaddingError { part: String, msg: String },
30}
31
32pub type Result<T> = std::result::Result<T, RangeSetError>;
33
34fn sort_key(s: &str) -> (i64, i64, String) {
42 if s.starts_with('-') {
43 let ival: i64 = s.parse().unwrap_or(0);
44 (-(s.len() as i64), ival, String::new())
45 } else {
46 (s.len() as i64, 0, s.to_string())
47 }
48}
49
50fn sorted_elements(elements: &BTreeSet<String>) -> Vec<String> {
51 let mut v: Vec<String> = elements.iter().cloned().collect();
52 v.sort_by(|a, b| sort_key(a).cmp(&sort_key(b)));
53 v
54}
55
56fn normalized_index_bounds(length: usize, start: isize, stop: Option<isize>) -> (usize, usize) {
60 let start = if start < 0 {
61 (length as isize + start).max(0) as usize
62 } else {
63 start as usize
64 };
65 let stop = match stop {
66 None => length,
67 Some(s) if s < 0 => (length as isize + s).max(0) as usize,
68 Some(s) => s as usize,
69 };
70 (start, stop)
71}
72
73#[derive(Debug, Clone)]
78struct RangeSlice {
79 start: i64,
80 stop: i64, step: i64,
82 pad: usize,
83}
84
85#[derive(Debug, Clone)]
92pub struct RangeSet {
93 elements: BTreeSet<String>,
95 _autostep: f64,
98}
99
100impl RangeSet {
101 pub fn new() -> Self {
103 Self {
104 elements: BTreeSet::new(),
105 _autostep: AUTOSTEP_DISABLED,
106 }
107 }
108
109 pub fn parse(pattern: &str, autostep: Option<u32>) -> Result<Self> {
114 let mut rs = Self::new();
115 rs.set_autostep(autostep);
116 rs._parse(pattern)?;
117 Ok(rs)
118 }
119
120 pub fn from_optional_pattern(pattern: Option<&str>, autostep: Option<u32>) -> Result<Self> {
132 match pattern {
133 None => {
134 let mut rs = Self::new();
135 rs.set_autostep(autostep);
136 Ok(rs)
137 }
138 Some(p) => Self::parse(p, autostep),
139 }
140 }
141
142 fn _parse(&mut self, pattern: &str) -> Result<()> {
144 for subrange in pattern.split(',') {
145 let subrange = subrange.trim();
146
147 let (baserange, step) = if subrange.contains('/') {
148 let parts: Vec<&str> = subrange.splitn(2, '/').collect();
149 let step_str = parts[1];
150 let step: i64 = step_str.parse().map_err(|_| RangeSetError::ParseError {
151 part: subrange.to_string(),
152 msg: "cannot convert string to integer".to_string(),
153 })?;
154 (parts[0], step)
155 } else {
156 (subrange, 1i64)
157 };
158
159 let (begin_str, end_str, _begin_sign, _end_sign) =
161 self.parse_range_part(baserange, subrange, step)?;
162
163 let (start, stop, pad) = self.compute_padding(&begin_str, &end_str, subrange)?;
165
166 if stop > 1e100 as i64 || start > stop || step < 1 {
168 return Err(RangeSetError::ParseError {
169 part: subrange.to_string(),
170 msg: "invalid values in range".to_string(),
171 });
172 }
173
174 self.add_range(start, stop + 1, step, pad as u32);
175 }
176 Ok(())
177 }
178
179 fn parse_range_part<'a>(
181 &self,
182 baserange: &'a str,
183 subrange: &str,
184 step: i64,
185 ) -> Result<(String, String, i64, i64)> {
186 if !baserange.contains('-') {
187 if step != 1 {
189 return Err(RangeSetError::ParseError {
190 part: subrange.to_string(),
191 msg: "invalid step usage".to_string(),
192 });
193 }
194 return Ok((baserange.to_string(), baserange.to_string(), 1, 1));
195 }
196
197 let parts: Vec<&str> = baserange.split('-').collect();
199 match parts.len() {
200 2 => {
201 let begin = parts[0].trim().to_string();
203 let end = parts[1].trim().to_string();
204 if begin.is_empty() {
205 if end.is_empty() {
207 return Err(RangeSetError::ParseError {
208 part: subrange.to_string(),
209 msg: "cannot convert string to integer".to_string(),
210 });
211 }
212 return Ok((end.clone(), end, -1, -1));
213 }
214 Ok((begin, end, 1, 1))
215 }
216 3 => {
217 let begin = parts[1].trim().to_string();
219 let end = parts[2].trim().to_string();
220 Ok((begin, end, -1, 1))
221 }
222 4 => {
223 let begin = parts[1].trim().to_string();
225 let end = parts[3].trim().to_string();
226 Ok((begin, end, -1, -1))
227 }
228 _ => Err(RangeSetError::ParseError {
229 part: subrange.to_string(),
230 msg: "cannot convert string to integer".to_string(),
231 }),
232 }
233 }
234
235 fn compute_padding(&self, begin: &str, end: &str, subrange: &str) -> Result<(i64, i64, usize)> {
237 let mut pad: usize = 0;
238
239 let begin_int: i64 = begin.parse().map_err(|_| {
241 if subrange.is_empty() {
242 RangeSetError::ParseError {
243 part: subrange.to_string(),
244 msg: "empty range".to_string(),
245 }
246 } else {
247 RangeSetError::ParseError {
248 part: subrange.to_string(),
249 msg: "cannot convert string to integer".to_string(),
250 }
251 }
252 })?;
253
254 if begin_int != 0 {
255 let begins = begin.trim_start_matches('0');
256 if begin.len() - begins.len() > 0 {
257 pad = begin.len();
258 }
259 } else if begin.len() > 1 {
260 pad = begin.len();
261 }
262
263 let end_trimmed = if end.parse::<i64>().unwrap_or(1) != 0 {
265 end.trim_start_matches('0')
266 } else {
267 end
268 };
269
270 let mut endpad: usize = 0;
271 if end.len() - end_trimmed.len() > 0 {
272 endpad = end.len();
273 }
274
275 if (pad > 0 || endpad > 0) && begin.len() != end.len() {
277 return Err(RangeSetError::ParseError {
278 part: subrange.to_string(),
279 msg: "padding length mismatch".to_string(),
280 });
281 }
282
283 let end_int: i64 = end_trimmed.parse().map_err(|_| RangeSetError::ParseError {
284 part: subrange.to_string(),
285 msg: "cannot convert string to integer".to_string(),
286 })?;
287
288 Ok((begin_int, end_int, pad))
289 }
290
291 pub fn add_range(&mut self, start: i64, stop: i64, step: i64, pad: u32) {
293 assert!(start < stop, "please provide ordered node index ranges");
294 assert!(step > 0);
295 assert!(stop - start < 1_000_000_000, "range too large");
296
297 let mut i = start;
298 while i < stop {
299 if pad == 0 {
300 self.elements.insert(format!("{}", i));
301 } else {
302 self.elements
303 .insert(format!("{:0>width$}", i, width = pad as usize));
304 }
305 i += step;
306 }
307 }
308
309 pub fn len(&self) -> usize {
311 self.elements.len()
312 }
313
314 pub fn is_empty(&self) -> bool {
316 self.elements.is_empty()
317 }
318
319 pub fn add_str(&mut self, s: &str) {
321 self.elements.insert(s.to_string());
322 }
323
324 pub fn add_int(&mut self, value: i64, pad: u32) {
326 if pad == 0 {
327 self.elements.insert(format!("{}", value));
328 } else {
329 self.elements
330 .insert(format!("{:0>width$}", value, width = pad as usize));
331 }
332 }
333
334 pub fn remove_str(&mut self, s: &str) {
336 if !self.elements.remove(s) {
337 panic!("element '{}' not found in RangeSet", s);
338 }
339 }
340
341 pub fn discard_str(&mut self, s: &str) {
343 self.elements.remove(s);
344 }
345
346 pub fn contains_str(&self, s: &str) -> bool {
348 self.elements.contains(s)
349 }
350
351 pub fn contains_int(&self, value: i64) -> bool {
353 self.elements.contains(&format!("{}", value))
354 }
355
356 pub fn index(&self, value: u64) -> Option<usize> {
368 self.index_str(&value.to_string())
369 }
370
371 pub fn index_str(&self, key: &str) -> Option<usize> {
374 self.index_str_within(key, 0, None)
375 }
376
377 pub fn index_str_within(&self, key: &str, start: isize, stop: Option<isize>) -> Option<usize> {
383 if !self.elements.contains(key) {
385 return None;
386 }
387 let tkey = sort_key(key);
390 let found = self
391 .elements
392 .iter()
393 .filter(|elem| sort_key(elem) < tkey)
394 .count();
395 if start != 0 || stop.is_some() {
396 let (start, stop) = normalized_index_bounds(self.len(), start, stop);
397 if !(start <= found && found < stop) {
398 return None;
399 }
400 }
401 Some(found)
402 }
403
404 pub fn sorted(&self) -> Vec<String> {
406 sorted_elements(&self.elements)
407 }
408
409 pub fn striter(&self) -> impl Iterator<Item = String> {
411 sorted_elements(&self.elements).into_iter()
412 }
413
414 pub fn intiter(&self) -> impl Iterator<Item = i64> {
416 sorted_elements(&self.elements)
417 .into_iter()
418 .map(|s| s.parse::<i64>().unwrap_or(0))
419 }
420
421 pub fn union(&self, other: &RangeSet) -> RangeSet {
427 let mut result = self.clone();
428 result.update(other);
429 result
430 }
431
432 pub fn intersection(&self, other: &RangeSet) -> RangeSet {
434 let mut result = self.clone();
435 result.intersection_update(other);
436 result
437 }
438
439 pub fn difference(&self, other: &RangeSet) -> RangeSet {
441 let mut result = self.clone();
442 result.difference_update(other);
443 result
444 }
445
446 pub fn symmetric_difference(&self, other: &RangeSet) -> RangeSet {
448 let mut result = self.clone();
449 result.symmetric_difference_update(other);
450 result
451 }
452
453 pub fn update(&mut self, other: &RangeSet) {
455 for elem in &other.elements {
456 self.elements.insert(elem.clone());
457 }
458 }
459
460 pub fn intersection_update(&mut self, other: &RangeSet) {
462 self.elements = self
463 .elements
464 .intersection(&other.elements)
465 .cloned()
466 .collect();
467 }
468
469 pub fn difference_update(&mut self, other: &RangeSet) {
471 self.elements = self.elements.difference(&other.elements).cloned().collect();
472 }
473
474 pub fn symmetric_difference_update(&mut self, other: &RangeSet) {
476 self.elements = self
477 .elements
478 .symmetric_difference(&other.elements)
479 .cloned()
480 .collect();
481 }
482
483 pub fn autostep(&self) -> Option<u32> {
489 if self._autostep >= AUTOSTEP_DISABLED {
490 None
491 } else {
492 Some((self._autostep as u32) + 1)
493 }
494 }
495
496 pub fn set_autostep(&mut self, val: Option<u32>) {
498 match val {
499 None => self._autostep = AUTOSTEP_DISABLED,
500 Some(v) => self._autostep = (v as f64) - 1.0,
501 }
502 }
503
504 fn slices_padding(&self, autostep: f64) -> Vec<RangeSlice> {
511 let sorted = sorted_elements(&self.elements);
512 if sorted.is_empty() {
513 return Vec::new();
514 }
515
516 let mut result: Vec<RangeSlice> = Vec::new();
517
518 let mut cur_pad: usize = 0;
519 let mut cur_padded: bool = false;
520 let mut cur_start: Option<i64> = None;
521 let mut cur_step: Option<i64> = None;
522 let mut last_idx: i64 = 0;
523
524 for si in &sorted {
525 let idx: i64 = si.parse().unwrap_or(0);
526 let digitlen = si.len();
527 let padded = digitlen > 1 && si.starts_with('0');
528
529 if let Some(cs) = cur_start {
530 let padding_mismatch = if cur_padded {
532 digitlen != cur_pad
533 } else {
534 padded
535 };
536
537 let step_mismatch = if let Some(cstep) = cur_step {
539 cstep != idx - last_idx
540 } else {
541 false
542 };
543
544 if padding_mismatch || step_mismatch {
545 let (stepped, step) = if let Some(cstep) = cur_step {
546 let stepped =
547 (cstep == 1) || ((last_idx - cs) as f64 >= autostep * cstep as f64);
548 (stepped, cstep)
549 } else {
550 (true, 1i64)
551 };
552
553 if stepped {
554 result.push(RangeSlice {
555 start: cs,
556 stop: last_idx + 1,
557 step,
558 pad: if cur_padded { cur_pad } else { 0 },
559 });
560 cur_start = Some(idx);
561 cur_padded = padded;
562 cur_pad = digitlen;
563 } else {
564 if padding_mismatch {
565 let stop = last_idx + 1;
566 let mut j = cs;
567 while j < stop {
568 result.push(RangeSlice {
569 start: j,
570 stop: j + 1,
571 step: 1,
572 pad: if cur_padded { cur_pad } else { 0 },
573 });
574 j += step;
575 }
576 cur_start = Some(idx);
577 cur_padded = padded;
578 cur_pad = digitlen;
579 } else {
580 let stop = last_idx - step + 1;
581 let mut j = cs;
582 while j < stop {
583 result.push(RangeSlice {
584 start: j,
585 stop: j + 1,
586 step: 1,
587 pad: if cur_padded { cur_pad } else { 0 },
588 });
589 j += step;
590 }
591 cur_start = Some(last_idx);
592 }
593 }
594
595 cur_step = if step_mismatch {
596 Some(idx - last_idx)
597 } else {
598 None
599 };
600 last_idx = idx;
601 continue;
602 }
603 } else {
604 cur_padded = padded;
606 cur_pad = digitlen;
607 cur_start = Some(idx);
608 cur_step = None;
609 last_idx = idx;
610 continue;
611 }
612
613 cur_step = Some(idx - last_idx);
614 last_idx = idx;
615 }
616
617 if let Some(cs) = cur_start {
619 if let Some(cstep) = cur_step {
620 let stepped = (last_idx - cs) as f64 >= self._autostep * cstep as f64;
621 if stepped || cstep == 1 {
622 result.push(RangeSlice {
623 start: cs,
624 stop: last_idx + 1,
625 step: cstep,
626 pad: if cur_padded { cur_pad } else { 0 },
627 });
628 } else {
629 let mut j = cs;
630 while j <= last_idx {
631 result.push(RangeSlice {
632 start: j,
633 stop: j + 1,
634 step: 1,
635 pad: if cur_padded { cur_pad } else { 0 },
636 });
637 j += cstep;
638 }
639 }
640 } else {
641 result.push(RangeSlice {
643 start: cs,
644 stop: last_idx + 1,
645 step: 1,
646 pad: if cur_padded { cur_pad } else { 0 },
647 });
648 }
649 }
650
651 result
652 }
653
654 fn folded_slices(&self) -> Vec<RangeSlice> {
656 self.slices_padding(self._autostep)
657 }
658
659 fn strslices(&self) -> Vec<String> {
661 self.folded_slices()
662 .iter()
663 .map(|sli| {
664 if sli.start + 1 == sli.stop {
665 if sli.pad > 0 {
667 format!("{:0>width$}", sli.start, width = sli.pad)
668 } else {
669 format!("{}", sli.start)
670 }
671 } else if sli.step == 1 {
672 if sli.pad > 0 {
674 format!(
675 "{:0>width$}-{:0>width$}",
676 sli.start,
677 sli.stop - 1,
678 width = sli.pad
679 )
680 } else {
681 format!("{}-{}", sli.start, sli.stop - 1)
682 }
683 } else {
684 if sli.pad > 0 {
686 format!(
687 "{:0>width$}-{:0>width$}/{}",
688 sli.start,
689 sli.stop - 1,
690 sli.step,
691 width = sli.pad
692 )
693 } else {
694 format!("{}-{}/{}", sli.start, sli.stop - 1, sli.step)
695 }
696 }
697 })
698 .collect()
699 }
700
701 pub fn padding(&self) -> Option<usize> {
703 let mut result = None;
704 for si in sorted_elements(&self.elements) {
705 let digitlen = si.len();
706 if digitlen > 1 && si.starts_with('0') {
707 result = Some(digitlen);
708 }
709 }
710 result
711 }
712}
713
714impl Default for RangeSet {
715 fn default() -> Self {
716 Self::new()
717 }
718}
719
720impl PartialEq for RangeSet {
721 fn eq(&self, other: &Self) -> bool {
724 self.elements == other.elements
725 }
726}
727
728impl fmt::Display for RangeSet {
729 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
730 write!(f, "{}", self.strslices().join(","))
731 }
732}
733
734#[derive(Debug, Clone)]
746pub struct RangeSetND {
747 pub vecrangesets: Vec<Vec<RangeSet>>,
748 _autostep: f64,
749}
750
751struct VecProductIter {
755 dims: Vec<Vec<String>>,
756 counter: Vec<usize>,
757 done: bool,
758}
759
760impl VecProductIter {
761 fn new(dims: Vec<Vec<String>>) -> Self {
762 let done = dims.iter().any(|d| d.is_empty());
763 Self {
764 counter: vec![0; dims.len()],
765 dims,
766 done,
767 }
768 }
769}
770
771impl Iterator for VecProductIter {
772 type Item = Vec<String>;
773
774 fn next(&mut self) -> Option<Self::Item> {
775 if self.done {
776 return None;
777 }
778 let item: Vec<String> = self
779 .dims
780 .iter()
781 .zip(&self.counter)
782 .map(|(d, &i)| d[i].clone())
783 .collect();
784 let mut pos = self.counter.len();
786 loop {
787 if pos == 0 {
788 self.done = true;
789 break;
790 }
791 pos -= 1;
792 self.counter[pos] += 1;
793 if self.counter[pos] < self.dims[pos].len() {
794 break;
795 }
796 self.counter[pos] = 0;
797 }
798 Some(item)
799 }
800}
801
802impl RangeSetND {
803 pub fn new(autostep: Option<u32>) -> Self {
804 Self {
805 vecrangesets: Vec::new(),
806 _autostep: autostep.map(|v| v as f64).unwrap_or(AUTOSTEP_DISABLED),
807 }
808 }
809
810 pub fn from_rangesets(vecrangesets: Vec<Vec<RangeSet>>, autostep: Option<u32>) -> Self {
813 Self {
814 vecrangesets,
815 _autostep: autostep.map(|v| v as f64).unwrap_or(AUTOSTEP_DISABLED),
816 }
817 }
818
819 pub fn len(&self) -> usize {
825 self.vecrangesets
826 .iter()
827 .map(|rgvec| rgvec.iter().map(RangeSet::len).product::<usize>())
828 .sum()
829 }
830
831 pub fn is_empty(&self) -> bool {
833 self.len() == 0
834 }
835
836 pub fn iter(&self) -> impl Iterator<Item = Vec<String>> + '_ {
841 self.vecrangesets
842 .iter()
843 .flat_map(|rgvec| VecProductIter::new(rgvec.iter().map(RangeSet::sorted).collect()))
844 }
845
846 pub fn index<T: ToString>(&self, elem: &[T]) -> Option<usize> {
856 self.index_within(elem, 0, None)
857 }
858
859 pub fn index_within<T: ToString>(
863 &self,
864 elem: &[T],
865 start: isize,
866 stop: Option<isize>,
867 ) -> Option<usize> {
868 let target: Vec<String> = elem.iter().map(|e| e.to_string()).collect();
869 for (pos, ivec) in self.iter().enumerate() {
870 if ivec == target {
871 if start != 0 || stop.is_some() {
872 let (start, stop) = normalized_index_bounds(self.len(), start, stop);
873 if !(start <= pos && pos < stop) {
874 break;
877 }
878 }
879 return Some(pos);
880 }
881 }
882 None
883 }
884}
885
886#[cfg(test)]
891mod tests {
892 use super::*;
893
894 fn test_rs(input: &str, expected: &str, expected_len: usize) {
895 let rs = RangeSet::parse(input, Some(3)).unwrap();
896 assert_eq!(
897 rs.to_string(),
898 expected,
899 "parse '{}' display mismatch",
900 input
901 );
902 assert_eq!(rs.len(), expected_len, "parse '{}' len mismatch", input);
903 }
904
905 #[test]
906 fn test_simple() {
907 test_rs("0", "0", 1);
908 test_rs("1", "1", 1);
909 test_rs("0-2", "0-2", 3);
910 test_rs("1-3", "1-3", 3);
911 test_rs("1-3,4-6", "1-6", 6);
912 test_rs("1-3,4-6,7-10", "1-10", 10);
913 }
914
915 #[test]
916 fn test_step_simple() {
917 test_rs("0-4/2", "0-4/2", 3);
918 test_rs("1-4/2", "1,3", 2);
919 test_rs("1-4/3", "1,4", 2);
920 test_rs("1-4/4", "1", 1);
921 }
922
923 #[test]
924 fn test_step_advanced() {
925 test_rs("1-4/4,2-6/2", "1-2,4,6", 4);
926 test_rs("6-24/6,9-21/6", "6-24/3", 7);
927 test_rs("0-24/2,9-21/2", "0-8/2,9-22,24", 20);
928 test_rs("0-24/2,9-21/2,100", "0-8/2,9-22,24,100", 21);
929 test_rs("3-21/9,6-24/9,9-27/9", "3-27/3", 9);
930 test_rs("1-17/2,2-18/2", "1-18", 18);
931 test_rs("1-17/01", "1-17", 17);
932 test_rs("1-17/02", "1-17/2", 9);
933 test_rs("1-17/03", "1-16/3", 6);
934 }
935
936 #[test]
937 fn test_step_advanced_more() {
938 test_rs("0-24/2,9-21/2,100-101", "0-8/2,9-22,24,100-101", 22);
939 test_rs("101-121/4,1-225/112", "1,101-121/4,225", 8);
940 test_rs("1-32/3,13-28/9", "1-31/3", 11);
941 test_rs("1-32/3,13-22/9", "1-31/3", 11);
942 test_rs("1-32/3,13-31/9", "1-31/3", 11);
943 test_rs("1-32/3,13-40/9", "1-31/3,40", 12);
944 }
945
946 #[test]
947 fn test_step_more_complex() {
948 test_rs("1-16/3,13-28/6", "1-19/3,25", 8);
949 test_rs("1-16/3,1-16/6", "1-16/3", 6);
950 test_rs("1-16/6,1-16/3", "1-16/3", 6);
951 test_rs("1-17/2,33-41/2,2-18/2", "1-18,33-41/2", 23);
952 test_rs("1-17/2,33-41/2,2-20/2", "1-18,20,33-41/2", 24);
953 test_rs("1-17/2,33-41/2,2-19/2", "1-18,33-41/2", 23);
954 }
955
956 #[test]
957 fn test_bad_syntax() {
958 assert!(RangeSet::parse("", None).is_err());
959 assert!(RangeSet::parse("-", None).is_err());
960 assert!(RangeSet::parse("A", None).is_err());
961 assert!(RangeSet::parse("2-5/a", None).is_err());
962 assert!(RangeSet::parse("3/2", None).is_err());
963 assert!(RangeSet::parse("3-/2", None).is_err());
964 assert!(RangeSet::parse("-/2", None).is_err());
965 assert!(RangeSet::parse("4-a/2", None).is_err());
966 assert!(RangeSet::parse("4-3/2", None).is_err());
967 assert!(RangeSet::parse("4-5/-2", None).is_err());
968 assert!(RangeSet::parse("004-002", None).is_err());
969 }
970
971 #[test]
972 fn test_intersection() {
973 let mut r1 = RangeSet::parse("4-34", None).unwrap();
974 let r2 = RangeSet::parse("27-42", None).unwrap();
975 r1.intersection_update(&r2);
976 assert_eq!(r1.to_string(), "27-34");
977 assert_eq!(r1.len(), 8);
978 }
979
980 #[test]
981 fn test_intersection_complex() {
982 let mut r1 = RangeSet::parse("2-450,654-700,800", None).unwrap();
983 let r2 = RangeSet::parse("500-502,690-820,830-840,900", None).unwrap();
984 r1.intersection_update(&r2);
985 assert_eq!(r1.to_string(), "690-700,800");
986 assert_eq!(r1.len(), 12);
987 }
988
989 #[test]
990 fn test_intersection_step() {
991 let mut r1 = RangeSet::parse("4-34/2", None).unwrap();
992 let r2 = RangeSet::parse("28-42/2", None).unwrap();
993 r1.intersection_update(&r2);
994 assert_eq!(r1.to_string(), "28,30,32,34");
995 assert_eq!(r1.len(), 4);
996
997 let mut r1 = RangeSet::parse("4-34/2", None).unwrap();
998 let r2 = RangeSet::parse("27-42/2", None).unwrap();
999 r1.intersection_update(&r2);
1000 assert_eq!(r1.to_string(), "");
1001 assert_eq!(r1.len(), 0);
1002
1003 let mut r1 = RangeSet::parse("2-60/3", Some(3)).unwrap();
1004 let r2 = RangeSet::parse("3-50/2", Some(3)).unwrap();
1005 r1.intersection_update(&r2);
1006 assert_eq!(r1.to_string(), "5-47/6");
1007 assert_eq!(r1.len(), 8);
1008 }
1009
1010 #[test]
1011 fn test_difference() {
1012 let mut r1 = RangeSet::parse("4,7-33", None).unwrap();
1013 let r2 = RangeSet::parse("8-33", None).unwrap();
1014 r1.difference_update(&r2);
1015 assert_eq!(r1.to_string(), "4,7");
1016 assert_eq!(r1.len(), 2);
1017 }
1018
1019 #[test]
1020 fn test_difference_bounds() {
1021 let mut r1 = RangeSet::parse("1-10,39-41,50-60", None).unwrap();
1022 let r2 = RangeSet::parse("1-10,38-39,50-60", None).unwrap();
1023 r1.difference_update(&r2);
1024 assert_eq!(r1.len(), 2);
1025 assert_eq!(r1.to_string(), "40-41");
1026 }
1027
1028 #[test]
1029 fn test_symmetric_difference() {
1030 let mut r1 = RangeSet::parse("4,7-33", None).unwrap();
1031 let r2 = RangeSet::parse("8-34", None).unwrap();
1032 r1.symmetric_difference_update(&r2);
1033 assert_eq!(r1.to_string(), "4,7,34");
1034 assert_eq!(r1.len(), 3);
1035 }
1036
1037 #[test]
1038 fn test_symmetric_difference_complex() {
1039 let mut r1 = RangeSet::parse("5,7,10-12,33-50", None).unwrap();
1040 let r2 = RangeSet::parse("8-34", None).unwrap();
1041 r1.symmetric_difference_update(&r2);
1042 assert_eq!(r1.to_string(), "5,7-9,13-32,35-50");
1043 assert_eq!(r1.len(), 40);
1044
1045 let mut r1 = RangeSet::parse("8-30", None).unwrap();
1046 let r2 = RangeSet::parse("31-40", None).unwrap();
1047 r1.symmetric_difference_update(&r2);
1048 assert_eq!(r1.to_string(), "8-40");
1049 assert_eq!(r1.len(), 33);
1050
1051 let mut r1 = RangeSet::parse("8-30", None).unwrap();
1052 let r2 = RangeSet::parse("8-30", None).unwrap();
1053 r1.symmetric_difference_update(&r2);
1054 assert_eq!(r1.to_string(), "");
1055 assert_eq!(r1.len(), 0);
1056 }
1057
1058 #[test]
1059 fn test_union() {
1060 let r1 = RangeSet::parse("1-10", None).unwrap();
1061 let r2 = RangeSet::parse("8-20", None).unwrap();
1062 let r3 = r1.union(&r2);
1063 assert_eq!(r3.to_string(), "1-20");
1064 assert_eq!(r3.len(), 20);
1065 }
1066
1067 #[test]
1068 fn test_contains() {
1069 let r1 = RangeSet::parse("1-100,102,105-242,800", None).unwrap();
1070 assert_eq!(r1.len(), 240);
1071 assert!(r1.contains_str("99"));
1072 assert!(!r1.contains_str("099"));
1073 assert!(!r1.contains_str("101"));
1074 }
1075
1076 #[test]
1077 fn test_padding() {
1078 let r1 = RangeSet::parse("001-010", None).unwrap();
1079 assert_eq!(r1.len(), 10);
1080 assert!(r1.contains_str("001"));
1081 assert!(r1.contains_str("010"));
1082 assert!(!r1.contains_str("1"));
1083 assert!(!r1.contains_str("10"));
1084
1085 let r2 = RangeSet::parse("00-02", None).unwrap();
1086 assert!(r2.contains_str("00"));
1087 assert!(!r2.contains_str("0"));
1088 assert!(r2.contains_str("01"));
1089 assert!(!r2.contains_str("1"));
1090
1091 let r3 = RangeSet::parse("0003-0143,0360-1000", None).unwrap();
1092 assert!(!r3.contains_str("360"));
1093 assert!(r3.contains_str("0360"));
1094 }
1095
1096 #[test]
1097 fn test_padding_display() {
1098 test_rs("001-010", "001-010", 10);
1099 test_rs("00-02", "00-02", 3);
1100 }
1101
1102 #[test]
1103 fn test_empty() {
1104 let rs = RangeSet::new();
1105 assert!(rs.is_empty());
1106 assert_eq!(rs.len(), 0);
1107 assert_eq!(rs.to_string(), "");
1108 }
1109
1110 #[test]
1111 fn test_add_remove() {
1112 let mut rs = RangeSet::new();
1113 rs.add_int(5, 0);
1114 rs.add_int(3, 0);
1115 rs.add_int(1, 0);
1116 assert_eq!(rs.len(), 3);
1117 assert_eq!(rs.to_string(), "1,3,5");
1118 rs.discard_str("3");
1119 assert_eq!(rs.len(), 2);
1120 assert_eq!(rs.to_string(), "1,5");
1121 }
1122
1123 #[test]
1124 fn test_intiter() {
1125 let rs = RangeSet::parse("3,1,5,10", None).unwrap();
1126 let vals: Vec<i64> = rs.intiter().collect();
1127 assert_eq!(vals, vec![1, 3, 5, 10]);
1128 }
1129
1130 #[test]
1131 fn test_large_range() {
1132 let rs = RangeSet::parse("1-1000", None).unwrap();
1133 assert_eq!(rs.len(), 1000);
1134 assert_eq!(rs.to_string(), "1-1000");
1135 }
1136
1137 #[test]
1138 fn test_diff_step() {
1139 let mut r1 = RangeSet::parse("4-34/2", Some(3)).unwrap();
1140 let r2 = RangeSet::parse("3-33/2", Some(3)).unwrap();
1141 r1.difference_update(&r2);
1142 assert_eq!(r1.to_string(), "4-34/2");
1143 assert_eq!(r1.len(), 16);
1144
1145 let mut r1 = RangeSet::parse("4-34/2", Some(3)).unwrap();
1146 let r2 = RangeSet::parse("2-14/2", Some(3)).unwrap();
1147 r1.difference_update(&r2);
1148 assert_eq!(r1.to_string(), "16-34/2");
1149 assert_eq!(r1.len(), 10);
1150
1151 let mut r1 = RangeSet::parse("4-34/2", Some(3)).unwrap();
1152 let r2 = RangeSet::parse("28-52/2", Some(3)).unwrap();
1153 r1.difference_update(&r2);
1154 assert_eq!(r1.to_string(), "4-26/2");
1155 assert_eq!(r1.len(), 12);
1156
1157 let mut r1 = RangeSet::parse("4-34/2", Some(3)).unwrap();
1158 let r2 = RangeSet::parse("12-18/2", Some(3)).unwrap();
1159 r1.difference_update(&r2);
1160 assert_eq!(r1.to_string(), "4-10/2,20-34/2");
1161 assert_eq!(r1.len(), 12);
1162 }
1163
1164 #[test]
1165 fn test_diff_step_complex() {
1166 let mut r1 = RangeSet::parse("1-100", Some(3)).unwrap();
1167 let r2 = RangeSet::parse("2-98/2", Some(3)).unwrap();
1168 r1.difference_update(&r2);
1169 assert_eq!(r1.to_string(), "1-99/2,100");
1170 assert_eq!(r1.len(), 51);
1171
1172 let mut r1 = RangeSet::parse("1-1000", Some(3)).unwrap();
1173 let r2 = RangeSet::parse("2-999/2", Some(3)).unwrap();
1174 r1.difference_update(&r2);
1175 assert_eq!(r1.to_string(), "1-999/2,1000");
1176 assert_eq!(r1.len(), 501);
1177 }
1178
1179 #[test]
1180 fn test_folding() {
1181 let r1 = RangeSet::parse(
1183 "112,114-117,119,121,130,132,134,136,138,139-141,144,147-148",
1184 Some(6),
1185 )
1186 .unwrap();
1187 assert_eq!(
1188 r1.to_string(),
1189 "112,114-117,119,121,130,132,134,136,138-141,144,147-148"
1190 );
1191
1192 let r1 = RangeSet::parse(
1193 "112,114-117,119,121,130,132,134,136,138,139-141,144,147-148",
1194 Some(5),
1195 )
1196 .unwrap();
1197 assert_eq!(
1198 r1.to_string(),
1199 "112,114-117,119,121,130-138/2,139-141,144,147-148"
1200 );
1201
1202 let r1 = RangeSet::parse("1,3-4,6,8", None).unwrap();
1203 assert_eq!(r1.to_string(), "1,3-4,6,8");
1204
1205 let r1 = RangeSet::parse("1,3-4,6,8", Some(4)).unwrap();
1206 assert_eq!(r1.to_string(), "1,3-4,6,8");
1207
1208 let r1 = RangeSet::parse("1,3-4,6,8", Some(2)).unwrap();
1209 assert_eq!(r1.to_string(), "1-3/2,4,6-8/2");
1210
1211 let r1 = RangeSet::parse("1,3-4,6,8", Some(3)).unwrap();
1212 assert_eq!(r1.to_string(), "1,3-4,6,8");
1213 }
1214
1215 #[test]
1216 fn test_mixed_padding() {
1217 let r0 = RangeSet::parse("030-031,032-100/2,101-489", Some(3)).unwrap();
1219 assert_eq!(r0.to_string(), "030-032,034-100/2,101-489");
1220
1221 let r1 = RangeSet::parse("030-032,033-100/3,102", Some(3)).unwrap();
1222 assert_eq!(r1.to_string(), "030-033,036-102/3");
1223
1224 let r2 = RangeSet::parse("030-032,033-100/3,101", Some(3)).unwrap();
1225 assert_eq!(r2.to_string(), "030-033,036-099/3,101");
1226
1227 let r3 = RangeSet::parse("030-032,033-100/3,100", Some(3)).unwrap();
1228 assert_eq!(r3.to_string(), "030-033,036-099/3,100");
1229 }
1230
1231 #[test]
1232 fn test_mixed_padding_with_different_widths() {
1233 let r5 = RangeSet::parse("030-032,033-100/3,99-105/3,0001", Some(3)).unwrap();
1235 assert_eq!(r5.to_string(), "99,030-033,036-105/3,0001");
1236 }
1237
1238 #[test]
1239 fn test_padding_mismatch_errors() {
1240 assert!(RangeSet::parse("1-044", None).is_err());
1242 assert!(RangeSet::parse("01-044", None).is_err());
1243 assert!(RangeSet::parse("001-44", None).is_err());
1244 assert!(RangeSet::parse("0-9,1-044", None).is_err());
1245 assert!(RangeSet::parse("0-9,01-044", None).is_err());
1246 assert!(RangeSet::parse("0-9,001-44", None).is_err());
1247 assert!(RangeSet::parse("030-032,033-99/3,100", None).is_err());
1248 }
1249
1250 #[test]
1251 fn test_update_complex() {
1252 let mut r1 = RangeSet::parse("1-100,102,105-242,800", None).unwrap();
1254 assert_eq!(r1.len(), 240);
1255 let r2 = RangeSet::parse("243-799,1924-1984", None).unwrap();
1256 assert_eq!(r2.len(), 618);
1257 r1.update(&r2);
1258 assert_eq!(r1.len(), 240 + 618);
1259 assert_eq!(r1.to_string(), "1-100,102,105-800,1924-1984");
1260 }
1261
1262 #[test]
1263 fn test_union_complex() {
1264 let r1 = RangeSet::parse("1-100,102,105-242,800", None).unwrap();
1266 let r2 = RangeSet::parse("243-799,1924-1984", None).unwrap();
1267 let r3 = r1.union(&r2);
1268 assert_eq!(r3.len(), 858);
1269 assert_eq!(r3.to_string(), "1-100,102,105-800,1924-1984");
1270
1271 let r2 = RangeSet::parse("200-799", None).unwrap();
1273 let r3 = r1.union(&r2);
1274 assert_eq!(r3.len(), 797);
1275 assert_eq!(r3.to_string(), "1-100,102,105-800");
1276 }
1277
1278 #[test]
1279 fn test_intersection_length() {
1280 let r1 = RangeSet::parse("115-117,130,166-170,4780-4999", None).unwrap();
1282 assert_eq!(r1.len(), 229);
1283 let r2 = RangeSet::parse("116-117,130,4781-4999", None).unwrap();
1284 assert_eq!(r2.len(), 222);
1285 let res = r1.intersection(&r2);
1286 assert_eq!(res.len(), 222);
1287
1288 let r1 = RangeSet::parse("115-200", None).unwrap();
1289 assert_eq!(r1.len(), 86);
1290 let r2 = RangeSet::parse("116-117,119,123-131,133,149,199", None).unwrap();
1291 assert_eq!(r2.len(), 15);
1292 let res = r1.intersection(&r2);
1293 assert_eq!(res.len(), 15);
1294
1295 let r1 = RangeSet::parse("115-117,130,166-170,4780-4999,5003", None).unwrap();
1297 assert_eq!(r1.len(), 230);
1298 let r2 = RangeSet::parse("116-117,130,4781-4999", None).unwrap();
1299 assert_eq!(r2.len(), 222);
1300 let res = r1.intersection(&r2);
1301 assert_eq!(res.len(), 222);
1302
1303 let r1 = RangeSet::parse("130,166-170,4780-4999", None).unwrap();
1305 assert_eq!(r1.len(), 226);
1306 let r2 = RangeSet::parse("116-117", None).unwrap();
1307 assert_eq!(r2.len(), 2);
1308 let res = r1.intersection(&r2);
1309 assert_eq!(res.len(), 0);
1310 }
1311
1312 #[test]
1313 fn test_ior() {
1314 let mut r1 = RangeSet::parse("1,3-9,14-21,30-39,42", None).unwrap();
1316 let r2 = RangeSet::parse("2-5,10-32,35,40-41", None).unwrap();
1317 r1.update(&r2);
1318 assert_eq!(r1.len(), 42);
1319 assert_eq!(r1.to_string(), "1-42");
1320 }
1321
1322 #[test]
1323 fn test_iand() {
1324 let mut r1 = RangeSet::parse("1,3-9,14-21,30-39,42", None).unwrap();
1326 let r2 = RangeSet::parse("2-5,10-32,35,40-41", None).unwrap();
1327 r1.intersection_update(&r2);
1328 assert_eq!(r1.len(), 15);
1329 assert_eq!(r1.to_string(), "3-5,14-21,30-32,35");
1330 }
1331
1332 #[test]
1333 fn test_ixor() {
1334 let mut r1 = RangeSet::parse("1,3-9,14-21,30-39,42", None).unwrap();
1336 let r2 = RangeSet::parse("2-5,10-32,35,40-41", None).unwrap();
1337 r1.symmetric_difference_update(&r2);
1338 assert_eq!(r1.len(), 27);
1339 assert_eq!(r1.to_string(), "1-2,6-13,22-29,33-34,36-42");
1340 }
1341
1342 #[test]
1343 fn test_isub() {
1344 let mut r1 = RangeSet::parse("1,3-9,14-21,30-39,42", None).unwrap();
1346 let r2 = RangeSet::parse("2-5,10-32,35,40-41", None).unwrap();
1347 r1.difference_update(&r2);
1348 assert_eq!(r1.len(), 12);
1349 assert_eq!(r1.to_string(), "1,6-9,33-34,36-39,42");
1350 }
1351
1352 #[test]
1353 fn test_add_range_api() {
1354 let mut r1 = RangeSet::new();
1356 r1.add_range(1, 100, 1, 0);
1357 assert_eq!(r1.len(), 99);
1358 assert_eq!(r1.to_string(), "1-99");
1359 r1.add_range(40, 101, 1, 0);
1360 assert_eq!(r1.len(), 100);
1361 assert_eq!(r1.to_string(), "1-100");
1362 r1.add_range(399, 423, 2, 0);
1363 assert_eq!(r1.len(), 112);
1364 assert_eq!(
1365 r1.to_string(),
1366 "1-100,399,401,403,405,407,409,411,413,415,417,419,421"
1367 );
1368
1369 let mut r1 = RangeSet::new();
1371 r1.set_autostep(Some(3));
1372 r1.add_range(1, 100, 1, 0);
1373 assert_eq!(r1.autostep(), Some(3));
1374 assert_eq!(r1.len(), 99);
1375 assert_eq!(r1.to_string(), "1-99");
1376 r1.add_range(40, 101, 1, 0);
1377 assert_eq!(r1.len(), 100);
1378 assert_eq!(r1.to_string(), "1-100");
1379 r1.add_range(399, 423, 2, 0);
1380 assert_eq!(r1.len(), 112);
1381 assert_eq!(r1.to_string(), "1-100,399-421/2");
1382 }
1383
1384 #[test]
1385 fn test_add_range_bounds() {
1386 let mut r1 = RangeSet::parse("1-30", Some(2)).unwrap();
1387 assert_eq!(r1.len(), 30);
1388 assert_eq!(r1.to_string(), "1-30");
1389 r1.add_range(32, 35, 1, 0);
1390 assert_eq!(r1.len(), 33);
1391 assert_eq!(r1.to_string(), "1-30,32-34");
1392 r1.add_range(31, 32, 1, 0);
1393 assert_eq!(r1.len(), 34);
1394 assert_eq!(r1.to_string(), "1-34");
1395
1396 let mut r1 = RangeSet::parse("1-30", Some(3)).unwrap();
1397 r1.add_range(40, 65, 10, 0);
1398 assert_eq!(r1.autostep(), Some(3));
1399 assert_eq!(r1.len(), 33);
1400 assert_eq!(r1.to_string(), "1-30,40-60/10");
1401
1402 r1.add_range(103, 104, 1, 0);
1404 assert_eq!(r1.len(), 34);
1405 assert_eq!(r1.to_string(), "1-30,40-60/10,103");
1406 }
1407
1408 #[test]
1409 fn test_autostep_property() {
1410 let mut rs = RangeSet::new();
1411 assert_eq!(rs.autostep(), None);
1412 rs.set_autostep(Some(3));
1413 assert_eq!(rs.autostep(), Some(3));
1414 rs.set_autostep(None);
1415 assert_eq!(rs.autostep(), None);
1416 }
1417
1418 #[test]
1419 fn test_padding_property() {
1420 let r1 = RangeSet::parse("001-010", None).unwrap();
1421 assert_eq!(r1.padding(), Some(3));
1422
1423 let r2 = RangeSet::parse("1-10", None).unwrap();
1424 assert_eq!(r2.padding(), None);
1425
1426 let r3 = RangeSet::parse("0003-0143,0360-1000", None).unwrap();
1427 assert_eq!(r3.padding(), Some(4));
1428 }
1429
1430 #[test]
1431 fn test_copy() {
1432 let rangeset = RangeSet::parse("115-117,130,166-170,4780-4999", None).unwrap();
1434 assert_eq!(rangeset.len(), 229);
1435 assert_eq!(rangeset.to_string(), "115-117,130,166-170,4780-4999");
1436 let mut r1 = rangeset.clone();
1437 let mut r2 = rangeset.clone();
1438 r1.remove_str("166");
1439 assert_eq!(rangeset.len(), r1.len() + 1);
1440 assert_eq!(rangeset.to_string(), "115-117,130,166-170,4780-4999");
1441 assert_eq!(r1.to_string(), "115-117,130,167-170,4780-4999");
1442 r2.update(&RangeSet::parse("118", None).unwrap());
1443 assert_eq!(rangeset.len() + 1, r2.len());
1444 assert_eq!(r2.to_string(), "115-118,130,166-170,4780-4999");
1445 }
1446
1447 #[test]
1448 fn test_remove_and_discard() {
1449 let mut r1 = RangeSet::parse("1-100,102,105-242,800", None).unwrap();
1451 assert_eq!(r1.len(), 240);
1452 r1.remove_str("100");
1453 assert_eq!(r1.len(), 239);
1454 assert_eq!(r1.to_string(), "1-99,102,105-242,800");
1455
1456 r1.discard_str("101"); r1.discard_str("105");
1458 assert_eq!(r1.len(), 238);
1459 assert_eq!(r1.to_string(), "1-99,102,106-242,800");
1460 }
1461
1462 #[test]
1463 #[should_panic(expected = "not found")]
1464 fn test_remove_missing_panics() {
1465 let mut r1 = RangeSet::parse("1-100", None).unwrap();
1466 r1.remove_str("101");
1467 }
1468
1469 #[test]
1470 fn test_index() {
1471 let r1 = RangeSet::parse("1-100,102,105-242,800", None).unwrap();
1473 let sorted = r1.sorted();
1475 for (i, elem) in sorted.iter().enumerate() {
1476 assert_eq!(r1.index_str(elem), Some(i));
1477 }
1478 assert_eq!(r1.index_str("1"), Some(0));
1480 assert_eq!(r1.index(1), Some(0));
1481 assert_eq!(r1.index_str("102"), Some(100));
1482 assert_eq!(r1.index(105), Some(101));
1483 assert_eq!(r1.index_str("800"), Some(239));
1484
1485 let r2 = RangeSet::parse("08-10", None).unwrap();
1487 assert_eq!(r2.index_str("08"), Some(0));
1488 assert_eq!(r2.index_str("09"), Some(1));
1489 assert_eq!(r2.index_str("10"), Some(2));
1490 assert_eq!(r2.index_str("9"), None);
1491 assert_eq!(r2.index(9), None);
1492 }
1493
1494 #[test]
1495 fn test_index_missing() {
1496 let r1 = RangeSet::parse("1-100,102,105-242,800", None).unwrap();
1499 assert_eq!(r1.index_str("101"), None);
1500 assert_eq!(r1.index(101), None);
1501 assert_eq!(r1.index(900), None);
1502 let r0 = RangeSet::new();
1504 assert_eq!(r0.index(0), None);
1505 assert_eq!(r0.index_str("0"), None);
1506 }
1507
1508 #[test]
1509 fn test_index_window() {
1510 let r3 = RangeSet::parse("0-9", None).unwrap();
1513 assert_eq!(r3.index_str_within("5", 3, None), Some(5));
1514 assert_eq!(r3.index_str_within("5", 5, None), Some(5));
1515 assert_eq!(r3.index_str_within("5", 6, None), None);
1516 assert_eq!(r3.index_str_within("8", -3, None), Some(8));
1517 assert_eq!(r3.index_str_within("5", 0, Some(6)), Some(5));
1518 assert_eq!(r3.index_str_within("5", 0, Some(5)), None);
1519 assert_eq!(r3.index_str_within("9", 0, Some(-1)), None);
1520 }
1521
1522 #[test]
1523 fn test_pickle_empty() {
1524 let rs = RangeSet::from_optional_pattern(None, Some(3)).unwrap();
1528 assert_eq!(rs, RangeSet::new());
1529 assert_eq!(rs.to_string(), "");
1530 assert_eq!(rs.len(), 0);
1531 assert_eq!(rs.autostep(), Some(3));
1532 let external = if rs.is_empty() {
1535 None
1536 } else {
1537 Some(rs.to_string())
1538 };
1539 let restored = RangeSet::from_optional_pattern(external.as_deref(), rs.autostep()).unwrap();
1540 assert_eq!(restored, rs);
1541 assert_eq!(restored.autostep(), Some(3));
1542 assert!(RangeSet::from_optional_pattern(Some(""), None).is_err());
1544 }
1545
1546 #[test]
1547 fn test_deepcopy_empty() {
1548 let rs = RangeSet::new().clone();
1551 assert_eq!(rs, RangeSet::new());
1552 assert_eq!(rs.to_string(), "");
1553 assert_eq!(rs.len(), 0);
1554 }
1555
1556 #[test]
1557 fn test_nd_index() {
1558 let rn1 = RangeSetND::from_rangesets(
1565 vec![
1566 vec![
1567 RangeSet::parse("0-3", None).unwrap(),
1568 RangeSet::parse("1-2", None).unwrap(),
1569 ],
1570 vec![
1571 RangeSet::parse("10", None).unwrap(),
1572 RangeSet::parse("10-13", None).unwrap(),
1573 ],
1574 ],
1575 None,
1576 );
1577 assert_eq!(rn1.len(), 12);
1578 for (i, ivec) in rn1.iter().enumerate() {
1580 assert_eq!(rn1.index(&ivec), Some(i));
1581 }
1582 assert_eq!(rn1.index(&["0", "1"]), Some(0));
1583 assert_eq!(rn1.index(&["3", "2"]), Some(7));
1584 assert_eq!(rn1.index(&["10", "13"]), Some(11));
1585 assert_eq!(rn1.index(&[0, 1]), Some(0));
1587 assert_eq!(rn1.index(&[10, 13]), Some(11));
1588 assert_eq!(rn1.index(&["10", "14"]), None);
1590 assert_eq!(rn1.index(&["5", "1"]), None);
1591 assert_eq!(rn1.index_within(&["3", "2"], 7, None), Some(7));
1597 assert_eq!(rn1.index_within(&["3", "2"], 8, None), None);
1598 assert_eq!(rn1.index_within(&["10", "13"], -1, None), Some(11));
1599 assert_eq!(rn1.index_within(&["10", "13"], 0, Some(12)), Some(11));
1600 assert_eq!(rn1.index_within(&["10", "13"], 0, Some(-1)), None);
1601 }
1602}