use py_comp::comp;
mod test_if_chains;
#[derive(Debug, PartialEq, Eq)]
struct Foo(i32);
#[derive(Debug)]
struct UncopyableIterator {}
impl Iterator for UncopyableIterator {
type Item = ();
fn next(&mut self) -> Option<Self::Item> {
None
}
}
#[derive(Debug)]
struct UncopyableIteratorOfUncopyableIterators {}
impl Iterator for UncopyableIteratorOfUncopyableIterators {
type Item = UncopyableIterator;
fn next(&mut self) -> Option<Self::Item> {
None
}
}
#[test]
fn basic_implementation_1_layer() {
let x = &[Foo(1), Foo(2)];
let mut xyz1 = Vec::new();
for a in x {
xyz1.push(a)
}
#[rustfmt::skip]
#[allow(clippy::into_iter_on_array)]
let xyz2 =
x
.into_iter()
.map(move |a| a)
.collect::<Vec<&Foo>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn basic_implementation_with_if_condition_1_layer() {
let x = &[Foo(1), Foo(2)];
let mut xyz1 = Vec::new();
for a in x {
if a.0 % 10 == 2 {
xyz1.push(a)
}
}
#[rustfmt::skip]
#[allow(clippy::into_iter_on_array)]
let xyz2 =
x
.into_iter()
.filter(|a| a.0 % 10 == 2)
.map(move |a| a)
.collect::<Vec<&Foo>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn basic_implementation_cartesian_4_layers() {
let w = &[Foo(1), Foo(2)];
let x = &[Foo(11), Foo(12)];
let y = &[Foo(21), Foo(22)];
let z = &[Foo(31), Foo(32)];
let mut xyz1 = Vec::new();
for a in w {
for b in x {
for c in y {
for d in z {
xyz1.push((a, b, c, d))
}
}
}
}
#[rustfmt::skip]
#[allow(clippy::into_iter_on_array)]
let xyz2 =
w
.into_iter()
.flat_map(move |a| {
x
.into_iter()
.flat_map(move |b| {
y
.into_iter()
.flat_map(move |c| {
z
.into_iter()
.map(move |d| {
(a, b, c, d)
})
})
})
})
.collect::<Vec<(&Foo, &Foo, &Foo, &Foo)>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn basic_implementation_cartesian_with_if_conditions_4_layers() {
let w = &[Foo(1), Foo(2)];
let x = &[Foo(11), Foo(12)];
let y = &[Foo(21), Foo(22)];
let z = &[Foo(31), Foo(32)];
let mut xyz1 = Vec::new();
for a in w.iter() {
if a.0 % 10 == 2 {
for b in x.iter() {
if b.0 % 10 == 2 {
for c in y.iter() {
if c.0 % 10 == 2 {
for d in z.iter() {
if d.0 % 10 == 2 {
xyz1.push((a, b, c, d))
}
}
}
}
}
}
}
}
#[rustfmt::skip]
#[allow(clippy::into_iter_on_array)]
let xyz2 =
w
.into_iter()
.filter(|a| a.0 % 10 == 2)
.flat_map(move |a| {
x
.into_iter()
.filter(|b| b.0 % 10 == 2)
.flat_map(move |b| {
y
.into_iter()
.filter(|c| c.0 % 10 == 2)
.flat_map(move |c| {
z
.into_iter()
.filter(|d| d.0 % 10 == 2)
.map(move |d| {
(a, b, c, d)
})
})
})
})
.collect::<Vec<(&Foo, &Foo, &Foo, &Foo)>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn various_forms_of_usage() {
let x = &[Foo(1), Foo(2)];
let y = &[[Foo(1), Foo(2)], [Foo(3), Foo(4)]];
let z = &[
[[Foo(1), Foo(2)], [Foo(3), Foo(4)]],
[[Foo(1), Foo(2)], [Foo(3), Foo(4)]],
];
let _ = comp!(a; for a in x);
let _ = comp!(a; for a in x;);
let _ = comp!(a; for a in x; if *a == Foo(123));
let _ = comp!(a; for a in x; if *a == Foo(123););
let _ = comp!(a; for x in y; for a in x);
let _ = comp!(a; for x in y; for a in x;);
let _ = comp!(a; for x in y; if x[0] == Foo(123); for a in x);
let _ = comp!(a; for x in y; if x[0] == Foo(123); for a in x;);
let _ = comp!(a; for x in y; for a in x; if x[0] == Foo(123));
let _ = comp!(a; for x in y; for a in x; if x[0] == Foo(123););
let _ = comp!(a; for y in z; for x in y; for a in x);
let _ = comp!(a; for y in z; for x in y; for a in x;);
let _ = comp!(a; for x in y; for a in x; if let Foo(1) | Foo(2) = a);
let _ = comp!(a; for x in y; for a in x; if let Foo(1) | Foo(2) = a;);
let _ = comp!(
(a, b);
for a in x; if let Foo(1) | Foo(2) = a;
for b in x; if let Foo(1) | Foo(2) = b
);
let _ = comp!(
(a, b);
for a in x; if let Foo(1) | Foo(2) = a;
for b in x; if let Foo(1) | Foo(2) = b;
);
}
#[test]
fn comp_1_layer() {
let x = &[Foo(1), Foo(2)];
let mut xyz1 = Vec::new();
for a in x {
xyz1.push(a)
}
let xyz2 = comp!(a; for a in x).collect::<Vec<&Foo>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn comp_with_if_condition_1_layer() {
let x = &[Foo(1), Foo(2)];
let mut xyz1 = Vec::new();
for a in x {
if a.0 % 10 == 2 {
xyz1.push(a)
}
}
let xyz2 = comp!(
a;
for a in x;
if a.0 % 10 == 2;
)
.collect::<Vec<&Foo>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn comp_with_if_let_condition_1_layer() {
let x = &[Foo(4), Foo(8)];
let mut xyz1 = Vec::new();
for a in x {
if let Foo(_inner @ 1...6) = a {
xyz1.push(a)
}
}
let xyz2 = comp!(
a;
for a in x;
if let Foo(_inner @ 1...6) = a;
)
.collect::<Vec<&Foo>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn comp_with_pattern_1_layer() {
let x = &[(Foo(1), Foo(2)), (Foo(3), Foo(4))];
let mut xyz1 = Vec::new();
for (a, _b) in x {
xyz1.push(a)
}
let xyz2 = comp!(a; for (a, _b) in x).collect::<Vec<&Foo>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn comp_with_pattern_with_if_condition_1_layer() {
let x = &[(Foo(1), Foo(2)), (Foo(3), Foo(4))];
let mut xyz1 = Vec::new();
for (a, _b) in x {
if a.0 % 10 == 2 {
xyz1.push(a)
}
}
let xyz2 = comp!(
a;
for (a, _b) in x;
if a.0 % 10 == 2;
)
.collect::<Vec<&Foo>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn comp_cartesian_4_layers() {
let w = &[Foo(1), Foo(2)];
let x = &[Foo(11), Foo(12)];
let y = &[Foo(21), Foo(22)];
let z = &[Foo(31), Foo(32)];
let mut xyz1 = Vec::new();
for a in w {
for b in x {
for c in y {
for d in z {
xyz1.push((a, b, c, d))
}
}
}
}
let xyz2 = comp!(
(a, b, c, d);
for a in w;
for b in x;
for c in y;
for d in z;
)
.collect::<Vec<(&Foo, &Foo, &Foo, &Foo)>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn comp_cartesian_with_if_conditions_4_layers() {
let w = &[Foo(1), Foo(2)];
let x = &[Foo(11), Foo(12)];
let y = &[Foo(21), Foo(22)];
let z = &[Foo(31), Foo(32)];
let mut xyz1 = Vec::new();
for a in w.iter() {
if a.0 % 10 == 2 {
for b in x.iter() {
if b.0 % 10 == 2 {
for c in y.iter() {
if c.0 % 10 == 2 {
for d in z.iter() {
if d.0 % 10 == 2 {
xyz1.push((a, b, c, d))
}
}
}
}
}
}
}
}
let xyz2 = comp!(
(a, b, c, d);
for a in w;
if a.0 % 10 == 2;
for b in x;
if b.0 % 10 == 2;
for c in y;
if c.0 % 10 == 2;
for d in z;
if d.0 % 10 == 2;
)
.collect::<Vec<(&Foo, &Foo, &Foo, &Foo)>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn comp_cartesian_with_if_and_if_let_conditions_4_layers() {
let w = &[Foo(1), Foo(2)];
let x = &[Foo(14), Foo(18)];
let y = &[Foo(21), Foo(22)];
let z = &[Foo(34), Foo(38)];
let mut xyz1 = Vec::new();
for a in w.iter() {
if a.0 % 10 == 2 {
for b in x.iter() {
if let Foo(_inner @ 11...16) = b {
for c in y.iter() {
if c.0 % 10 == 2 {
for d in z.iter() {
if let Foo(_inner @ 31...36) = d {
xyz1.push((a, b, c, d))
}
}
}
}
}
}
}
}
let xyz2 = comp!(
(a, b, c, d);
for a in w;
if a.0 % 10 == 2;
for b in x;
if let Foo(_inner @ 11...16) = b;
for c in y;
if c.0 % 10 == 2;
for d in z;
if let Foo(_inner @ 31...36) = d;
)
.collect::<Vec<(&Foo, &Foo, &Foo, &Foo)>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn comp_cartesian_with_pattern_4_layers() {
let w = &[(Foo(1), Foo(99)), (Foo(2), Foo(99))];
let x = &[(Foo(11), Foo(99)), (Foo(12), Foo(99))];
let y = &[(Foo(21), Foo(99)), (Foo(22), Foo(99))];
let z = &[(Foo(31), Foo(99)), (Foo(32), Foo(99))];
let mut xyz1 = Vec::new();
for (a, _a) in w {
for (b, _b) in x {
for (c, _c) in y {
for (d, _d) in z {
xyz1.push((a, b, c, d))
}
}
}
}
let xyz2 = comp!(
(a, b, c, d);
for (a, _a) in w;
for (b, _b) in x;
for (c, _c) in y;
for (d, _d) in z;
)
.collect::<Vec<(&Foo, &Foo, &Foo, &Foo)>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn comp_cartesian_with_pattern_with_if_conditions_4_layers() {
let w = &[(Foo(1), Foo(99)), (Foo(2), Foo(99))];
let x = &[(Foo(11), Foo(99)), (Foo(12), Foo(99))];
let y = &[(Foo(21), Foo(99)), (Foo(22), Foo(99))];
let z = &[(Foo(31), Foo(99)), (Foo(32), Foo(99))];
let mut xyz1 = Vec::new();
for (a, _a) in w.iter() {
if a.0 % 10 == 2 {
for (b, _b) in x.iter() {
if b.0 % 10 == 2 {
for (c, _c) in y.iter() {
if c.0 % 10 == 2 {
for (d, _d) in z.iter() {
if d.0 % 10 == 2 {
xyz1.push((a, b, c, d))
}
}
}
}
}
}
}
}
let xyz2 = comp!(
(a, b, c, d);
for (a, _a) in w;
if a.0 % 10 == 2;
for (b, _b) in x;
if b.0 % 10 == 2;
for (c, _c) in y;
if c.0 % 10 == 2;
for (d, _d) in z;
if d.0 % 10 == 2;
)
.collect::<Vec<(&Foo, &Foo, &Foo, &Foo)>>();
assert_eq!(xyz1, xyz2);
}
#[test]
fn triple_nested_structure() {
let nested_3 = &[
[
[Foo(0), Foo(1), Foo(2)],
[Foo(3), Foo(4), Foo(5)],
[Foo(6), Foo(7), Foo(8)],
],
[
[Foo(9), Foo(10), Foo(11)],
[Foo(12), Foo(13), Foo(14)],
[Foo(15), Foo(16), Foo(17)],
],
[
[Foo(18), Foo(19), Foo(20)],
[Foo(21), Foo(22), Foo(23)],
[Foo(24), Foo(25), Foo(26)],
],
];
let nested_objects = comp!(
{
let inner = nested.0;
Foo(inner + 1)
};
for nested_2 in nested_3;
for nested_1 in nested_2;
for nested in nested_1;
)
.collect::<Vec<Foo>>();
let expected_values = (1..28).map(Foo).collect::<Vec<Foo>>();
assert_eq!(expected_values, nested_objects);
}
#[test]
fn uncopyable_iterator() {
let _ = comp!(x; for x in UncopyableIterator {});
}
#[test]
fn uncopyable_iterator_of_uncopyable_iterators() {
let _ = comp!(
item;
for uncopyable_iterator in UncopyableIteratorOfUncopyableIterators {};
for item in uncopyable_iterator;
);
}
mod renamed_comp_import {
use py_comp::comp as c;
#[test]
fn use_renamed_macro() {
let _ = c!(y; for x in &[[0]]; for y in x);
}
}