|
1 | | -use crate::pyobject::PyObjectRef; |
| 1 | +use std::cell::RefCell; |
| 2 | +use std::ops::AddAssign; |
| 3 | + |
| 4 | +use num_bigint::BigInt; |
| 5 | + |
| 6 | +use crate::function::OptionalArg; |
| 7 | +use crate::obj::objint::{PyInt, PyIntRef}; |
| 8 | +use crate::obj::objtype::PyClassRef; |
| 9 | +use crate::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue}; |
2 | 10 | use crate::vm::VirtualMachine; |
3 | 11 |
|
| 12 | +#[pyclass] |
| 13 | +#[derive(Debug)] |
| 14 | +struct PyItertoolsCount { |
| 15 | + cur: RefCell<BigInt>, |
| 16 | + step: BigInt, |
| 17 | +} |
| 18 | + |
| 19 | +impl PyValue for PyItertoolsCount { |
| 20 | + fn class(vm: &VirtualMachine) -> PyClassRef { |
| 21 | + vm.class("itertools", "count") |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +#[pyimpl] |
| 26 | +impl PyItertoolsCount { |
| 27 | + #[pymethod(name = "__new__")] |
| 28 | + fn new( |
| 29 | + _cls: PyClassRef, |
| 30 | + start: OptionalArg<PyIntRef>, |
| 31 | + step: OptionalArg<PyIntRef>, |
| 32 | + vm: &VirtualMachine, |
| 33 | + ) -> PyResult { |
| 34 | + let start = match start.into_option() { |
| 35 | + Some(int) => int.as_bigint().clone(), |
| 36 | + None => BigInt::from(0), |
| 37 | + }; |
| 38 | + let step = match step.into_option() { |
| 39 | + Some(int) => int.as_bigint().clone(), |
| 40 | + None => BigInt::from(1), |
| 41 | + }; |
| 42 | + |
| 43 | + Ok(PyItertoolsCount { |
| 44 | + cur: RefCell::new(start), |
| 45 | + step: step, |
| 46 | + } |
| 47 | + .into_ref(vm) |
| 48 | + .into_object()) |
| 49 | + } |
| 50 | + |
| 51 | + #[pymethod(name = "__next__")] |
| 52 | + fn next(&self, _vm: &VirtualMachine) -> PyResult<PyInt> { |
| 53 | + let result = self.cur.borrow().clone(); |
| 54 | + AddAssign::add_assign(&mut self.cur.borrow_mut() as &mut BigInt, &self.step); |
| 55 | + Ok(PyInt::new(result)) |
| 56 | + } |
| 57 | + |
| 58 | + #[pymethod(name = "__iter__")] |
| 59 | + fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> { |
| 60 | + zelf |
| 61 | + } |
| 62 | +} |
| 63 | + |
4 | 64 | pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { |
| 65 | + let ctx = &vm.ctx; |
| 66 | + |
| 67 | + let count = ctx.new_class("count", ctx.object()); |
| 68 | + PyItertoolsCount::extend_class(ctx, &count); |
| 69 | + |
5 | 70 | py_module!(vm, "itertools", { |
| 71 | + "count" => count, |
6 | 72 | }) |
7 | 73 | } |
0 commit comments