[][src]Macro rustypy::unpack_pytype

macro_rules! unpack_pytype {
    ($t:ident; ($($p:tt,)+)) => { ... };
    ($pylist:ident; PyList{$t:tt => $type_:ty}) => { ... };
    ($pylist:ident; PyList { $o:tt { $($t:tt)* } }) => { ... };
    ($pydict:ident; PyDict{($kt:ty, $o:tt { $($t:tt)* })}) => { ... };
    ($pydict:ident; PyDict{($kt:ty, $t:tt => $type_:ty)}) => { ... };
}

Converts python data to std Rust collections or tuples, moving the data:

  • Consumes the content of a PyDict<K, T> as received from Python (raw pointer) and returns a HashMap<K, T> from it.
  • Consumes a PyList<PyArg(T)> content as recived from Python (raw pointer) and returns a Vec<T> from it.
  • Iterates over a a PyTuple and returns a corresponding Rust tuple. Moves the data leaving an empty PyTuple.

Inner containers (ie. PyList<PyArg(T)>) are converted to the respective Rust analog (ie. Vec<T>)

Examples

Unpack a PyTuple from Python:

// tuple from Python: ({"one": [0, 1, 3]}, {"two": [3, 2, 1]})
let unpacked = unpack_pytuple!(pytuple; ({PyDict{(PyString, PyList{I32 => i64})}},
                                         {PyDict{(PyString, PyList{I32 => i64})}},));

Unpack a PyList from Python:

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

Unpack a PyDict from Python:

let unpacked = unpack_pytype!(dict; PyDict{(i32, PyString => String)});

You can combine different containers and nest them:

// dict from Python: {str: ([u64], {i32: str})} as *mut size_t
let unpacked = unpack_pytype!(dict;
    PyDict{(PyString, PyTuple{({PyList{I64 => i64}},
                               {PyDict{(i32, PyString => String)}},)})}
    );