[][src]Macro rustypy::unpack_pylist

macro_rules! unpack_pylist {
    ( $pylist:ident; PyList { $o:tt { $($t:tt)* } } ) => { ... };
    ( $pytuple:ident; PyTuple { $t:tt } ) => { ... };
    ( $pylist:ident; PyList{$t:tt => $type_:ty} ) => { ... };
    ( $pydict:ident; PyDict{$t:tt} ) => { ... };
}

Consumes a PyList<PyArg(T)> content as recived from Python (raw pointer) and returns a Vec<T> from it, no copies are performed in the process.

All inner elements are moved out if possible, if not (like with PyTuples) are copied. PyTuple variants are destructured into Rust tuples which contain the appropiate Rust types (valid syntax for unpack_pytuple! macro must be provided). The same for other container types (inner PyList, PyDict, etc.).

Examples

A simple PyList which contains PyString types::

use rustypy::{PyList, PyString};
let string_list = PyList::from(vec!["Python", "in", "Rust"]).into_raw();
let unpacked = unpack_pylist!(string_list; PyList{PyString => PyString});

And an other with i32:

// list from python: [1, 1, 1, 1, 1]
let unpacked = unpack_pylist!(int_list; PyList{I32 => i32});

It can contain nested containers. A PyList which contains PyTuples which contain a list of i64 PyTuples and a single f32:

// list from Python: [([(i64; 3)], f32)]
let unpacked = unpack_pylist!(list;
    PyList{
        PyTuple{(
            {PyList{PyTuple{(I64, I64, I64,)}}}, F32,
        )}
    });
assert_eq!(vec![(vec![(1, 2, 3,)], 0.1), (vec![(3, 2, 1,)], 0.2)], unpacked);