forked from RustPython/RustPython
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiter.rs
53 lines (49 loc) · 1.67 KB
/
iter.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use crate::{types::PyComparisonOp, vm::VirtualMachine, PyObjectRef, PyResult};
use itertools::Itertools;
pub trait PyExactSizeIterator<'a>: ExactSizeIterator<Item = &'a PyObjectRef> + Sized {
fn eq(self, other: impl PyExactSizeIterator<'a>, vm: &VirtualMachine) -> PyResult<bool> {
let lhs = self;
let rhs = other;
if lhs.len() != rhs.len() {
return Ok(false);
}
for (a, b) in lhs.zip_eq(rhs) {
if !vm.identical_or_equal(a, b)? {
return Ok(false);
}
}
Ok(true)
}
fn richcompare(
self,
other: impl PyExactSizeIterator<'a>,
op: PyComparisonOp,
vm: &VirtualMachine,
) -> PyResult<bool> {
let less = match op {
PyComparisonOp::Eq => return PyExactSizeIterator::eq(self, other, vm),
PyComparisonOp::Ne => return PyExactSizeIterator::eq(self, other, vm).map(|eq| !eq),
PyComparisonOp::Lt | PyComparisonOp::Le => true,
PyComparisonOp::Gt | PyComparisonOp::Ge => false,
};
let lhs = self;
let rhs = other;
let lhs_len = lhs.len();
let rhs_len = rhs.len();
for (a, b) in lhs.zip(rhs) {
if vm.bool_eq(a, b)? {
continue;
}
let ret = if less {
vm.bool_seq_lt(a, b)?
} else {
vm.bool_seq_gt(a, b)?
};
if let Some(v) = ret {
return Ok(v);
}
}
Ok(op.eval_ord(lhs_len.cmp(&rhs_len)))
}
}
impl<'a, T> PyExactSizeIterator<'a> for T where T: ExactSizeIterator<Item = &'a PyObjectRef> + Sized {}