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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use crate::err::{PyErr, PyResult};
use crate::ffi::{self, Py_ssize_t};
use crate::instance::PyNativeType;
use crate::{AsPyPointer, PyAny, PyObject, Python, ToPyObject};
use std::os::raw::c_long;
#[repr(transparent)]
pub struct PySlice(PyAny);
pyobject_native_type!(
PySlice,
ffi::PySliceObject,
ffi::PySlice_Type,
ffi::PySlice_Check
);
pub struct PySliceIndices {
pub start: isize,
pub stop: isize,
pub step: isize,
pub slicelength: isize,
}
impl PySliceIndices {
pub fn new(start: isize, stop: isize, step: isize) -> PySliceIndices {
PySliceIndices {
start,
stop,
step,
slicelength: 0,
}
}
}
impl PySlice {
pub fn new(py: Python, start: isize, stop: isize, step: isize) -> &PySlice {
unsafe {
let ptr = ffi::PySlice_New(
ffi::PyLong_FromLong(start as c_long),
ffi::PyLong_FromLong(stop as c_long),
ffi::PyLong_FromLong(step as c_long),
);
py.from_owned_ptr(ptr)
}
}
#[inline]
pub fn indices(&self, length: c_long) -> PyResult<PySliceIndices> {
unsafe {
let slicelength: isize = 0;
let start: isize = 0;
let stop: isize = 0;
let step: isize = 0;
let r = ffi::PySlice_GetIndicesEx(
self.as_ptr(),
length as Py_ssize_t,
&start as *const _ as *mut _,
&stop as *const _ as *mut _,
&step as *const _ as *mut _,
&slicelength as *const _ as *mut _,
);
if r == 0 {
Ok(PySliceIndices {
start,
stop,
step,
slicelength,
})
} else {
Err(PyErr::fetch(self.py()))
}
}
}
}
impl ToPyObject for PySliceIndices {
fn to_object(&self, py: Python) -> PyObject {
PySlice::new(py, self.start, self.stop, self.step).into()
}
}