]> git.lizzy.rs Git - rust.git/blobdiff - library/core/tests/iter.rs
Auto merge of #81152 - lzutao:intersperse_fold, r=m-ou-se
[rust.git] / library / core / tests / iter.rs
index 7376e7848eff540a50832bf8a6eea4e1cdc08639..78b4d1acaf5cd3119d619b79dab7a2bbdf749136 100644 (file)
@@ -2,6 +2,7 @@
 
 use core::cell::Cell;
 use core::convert::TryFrom;
+use core::iter::TrustedRandomAccess;
 use core::iter::*;
 
 /// An iterator wrapper that panics whenever `next` or `next_back` is called
@@ -601,6 +602,26 @@ fn test_zip_nth_back_side_effects_exhausted() {
     assert_eq!(b, vec![200, 300, 400]);
 }
 
+#[test]
+fn test_zip_trusted_random_access_composition() {
+    let a = [0, 1, 2, 3, 4];
+    let b = a;
+    let c = a;
+
+    let a = a.iter().copied();
+    let b = b.iter().copied();
+    let mut c = c.iter().copied();
+    c.next();
+
+    let mut z1 = a.zip(b);
+    assert_eq!(z1.next().unwrap(), (0, 0));
+
+    let mut z2 = z1.zip(c);
+    fn assert_trusted_random_access<T: TrustedRandomAccess>(_a: &T) {}
+    assert_trusted_random_access(&z2);
+    assert_eq!(z2.next().unwrap(), ((1, 1), 1));
+}
+
 #[test]
 fn test_iterator_step_by() {
     // Identity
@@ -3508,6 +3529,12 @@ pub fn extend_for_unit() {
 
 #[test]
 fn test_intersperse() {
+    let v = std::iter::empty().intersperse(0u32).collect::<Vec<_>>();
+    assert_eq!(v, vec![]);
+
+    let v = std::iter::once(1).intersperse(0).collect::<Vec<_>>();
+    assert_eq!(v, vec![1]);
+
     let xs = ["a", "", "b", "c"];
     let v: Vec<&str> = xs.iter().map(|x| x.clone()).intersperse(", ").collect();
     let text: String = v.concat();
@@ -3520,6 +3547,9 @@ fn test_intersperse() {
 
 #[test]
 fn test_intersperse_size_hint() {
+    let iter = std::iter::empty::<i32>().intersperse(0);
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+
     let xs = ["a", "", "b", "c"];
     let mut iter = xs.iter().map(|x| x.clone()).intersperse(", ");
     assert_eq!(iter.size_hint(), (7, Some(7)));
@@ -3532,6 +3562,47 @@ fn test_intersperse_size_hint() {
     assert_eq!([].iter().intersperse(&()).size_hint(), (0, Some(0)));
 }
 
+#[test]
+fn test_intersperse_fold() {
+    let v = (1..4).intersperse(9).fold(Vec::new(), |mut acc, x| {
+        acc.push(x);
+        acc
+    });
+    assert_eq!(v.as_slice(), [1, 9, 2, 9, 3]);
+
+    let mut iter = (1..4).intersperse(9);
+    assert_eq!(iter.next(), Some(1));
+    let v = iter.fold(Vec::new(), |mut acc, x| {
+        acc.push(x);
+        acc
+    });
+    assert_eq!(v.as_slice(), [9, 2, 9, 3]);
+
+    struct NoneAtStart(i32); // Produces: None, Some(2), Some(3), None, ...
+    impl Iterator for NoneAtStart {
+        type Item = i32;
+        fn next(&mut self) -> Option<i32> {
+            self.0 += 1;
+            Some(self.0).filter(|i| i % 3 != 1)
+        }
+    }
+
+    let v = NoneAtStart(0).intersperse(1000).fold(0, |a, b| a + b);
+    assert_eq!(v, 0);
+}
+
+#[test]
+fn test_intersperse_collect_string() {
+    let contents = vec![1, 2, 3];
+
+    let contents_string = contents
+        .into_iter()
+        .map(|id| id.to_string())
+        .intersperse(", ".to_owned())
+        .collect::<String>();
+    assert_eq!(contents_string, "1, 2, 3");
+}
+
 #[test]
 fn test_fold_specialization_intersperse() {
     let mut iter = (1..2).intersperse(0);
@@ -3587,3 +3658,24 @@ fn test_try_fold_specialization_intersperse_err() {
     iter.try_for_each(|item| if item == "b" { None } else { Some(()) });
     assert_eq!(iter.next(), None);
 }
+
+#[test]
+fn test_intersperse_with() {
+    #[derive(PartialEq, Debug)]
+    struct NotClone {
+        u: u32,
+    }
+    let r = vec![NotClone { u: 0 }, NotClone { u: 1 }]
+        .into_iter()
+        .intersperse_with(|| NotClone { u: 2 })
+        .collect::<Vec<_>>();
+    assert_eq!(r, vec![NotClone { u: 0 }, NotClone { u: 2 }, NotClone { u: 1 }]);
+
+    let mut ctr = 100;
+    let separator = || {
+        ctr *= 2;
+        ctr
+    };
+    let r = (0..3).intersperse_with(separator).collect::<Vec<_>>();
+    assert_eq!(r, vec![0, 200, 1, 400, 2]);
+}