serde_pyobject/pylit.rs
1/// Create [`pyo3::types::PyDict`] from a list of key-value pairs.
2///
3/// Examples
4/// ---------
5///
6/// - When you have GIL marker `py`, you can pass it and get a Bound pointer `PyResult<Bound<PyDict>>`:
7///
8/// ```
9/// use pyo3::{Python, Bound, types::{PyDict, PyDictMethods, PyAnyMethods}};
10/// use serde_pyobject::pydict;
11///
12/// Python::attach(|py| {
13/// let dict: Bound<PyDict> = pydict! {
14/// py,
15/// "foo" => 42,
16/// "bar" => "baz"
17/// }
18/// .unwrap();
19///
20/// assert_eq!(
21/// dict.get_item("foo")
22/// .unwrap()
23/// .unwrap()
24/// .extract::<i32>()
25/// .unwrap(),
26/// 42
27/// );
28/// assert_eq!(
29/// dict.get_item("bar")
30/// .unwrap()
31/// .unwrap()
32/// .extract::<String>()
33/// .unwrap(),
34/// "baz",
35/// );
36/// })
37/// ```
38///
39/// - When you don't have GIL marker, you get a `PyResult<Py<PyDict>>`:
40///
41/// ```
42/// use pyo3::{Python, Py, types::{PyDict, PyDictMethods, PyAnyMethods}};
43/// use serde_pyobject::pydict;
44///
45/// let dict: Py<PyDict> = pydict! {
46/// "foo" => 42,
47/// "bar" => "baz"
48/// }
49/// .unwrap();
50///
51/// Python::attach(|py| {
52/// let dict = dict.into_bound(py);
53/// assert_eq!(
54/// dict.get_item("foo")
55/// .unwrap()
56/// .unwrap()
57/// .extract::<i32>()
58/// .unwrap(),
59/// 42
60/// );
61/// assert_eq!(
62/// dict.get_item("bar")
63/// .unwrap()
64/// .unwrap()
65/// .extract::<String>()
66/// .unwrap(),
67/// "baz",
68/// );
69/// })
70/// ```
71///
72#[macro_export]
73macro_rules! pydict {
74 ($py:expr, $($key:expr => $value:expr),*) => {
75 (|| -> $crate::pyo3::PyResult<$crate::pyo3::Bound<$crate::pyo3::types::PyDict>> {
76 use $crate::pyo3::types::PyDictMethods;
77 let dict = $crate::pyo3::types::PyDict::new($py);
78 $(dict.set_item($key, $value)?;)*
79 Ok(dict)
80 })()
81 };
82 ($($key:expr => $value:expr),*) => {
83 $crate::pyo3::Python::attach(|py| -> $crate::pyo3::PyResult<$crate::pyo3::Py<$crate::pyo3::types::PyDict>> {
84 let dict = pydict!(py, $($key => $value),*)?;
85 Ok(dict.into())
86 })
87 };
88}
89
90/// Create [`pyo3::types::PyList`] from a list of values.
91///
92/// Examples
93/// --------
94///
95/// - When you have GIL marker `py`, you can pass it and get a reference `PyResult<&PyList>`:
96///
97/// ```
98/// use pyo3::{Python, types::{PyList, PyListMethods, PyAnyMethods}};
99/// use serde_pyobject::pylist;
100///
101/// Python::attach(|py| {
102/// let list = pylist![py; 1, "two"].unwrap();
103/// assert_eq!(list.len(), 2);
104/// assert_eq!(list.get_item(0).unwrap().extract::<i32>().unwrap(), 1);
105/// assert_eq!(list.get_item(1).unwrap().extract::<String>().unwrap(), "two");
106/// })
107/// ```
108///
109/// - When you don't have GIL marker, you get a `PyResult<Py<PyList>>`:
110///
111/// ```
112/// use pyo3::{Python, Py, types::{PyList, PyListMethods, PyAnyMethods}};
113/// use serde_pyobject::pylist;
114///
115/// let list: Py<PyList> = pylist![1, "two"].unwrap();
116///
117/// Python::attach(|py| {
118/// let list = list.into_bound(py);
119/// assert_eq!(list.len(), 2);
120/// assert_eq!(list.get_item(0).unwrap().extract::<i32>().unwrap(), 1);
121/// assert_eq!(list.get_item(1).unwrap().extract::<String>().unwrap(), "two");
122/// });
123/// ```
124///
125#[macro_export]
126macro_rules! pylist {
127 ($py:expr; $($value:expr),*) => {
128 (|| -> $crate::pyo3::PyResult<$crate::pyo3::Bound<$crate::pyo3::types::PyList>> {
129 use $crate::pyo3::types::PyListMethods;
130 let list = $crate::pyo3::types::PyList::empty($py);
131 $(list.append($value)?;)*
132 Ok(list)
133 })()
134 };
135 ($($value:expr),*) => {
136 $crate::pyo3::Python::attach(|py| -> $crate::pyo3::PyResult<$crate::pyo3::Py<$crate::pyo3::types::PyList>> {
137 let list = pylist!(py; $($value),*)?;
138 Ok(list.into())
139 })
140 };
141}