Mercurial > hg
comparison rust/hg-cpython/src/ref_sharing.rs @ 42888:67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
See the previous commit for why. The docstring is moved accordingly.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 08 Sep 2019 12:23:18 +0900 |
parents | 706104dcb2c8 |
children | ea91a126c803 |
comparison
equal
deleted
inserted
replaced
42887:706104dcb2c8 | 42888:67853749961b |
---|---|
191 /// * `$inner_struct` is the identifier of the underlying Rust struct | 191 /// * `$inner_struct` is the identifier of the underlying Rust struct |
192 /// * `$data_member` is the identifier of the data member of `$inner_struct` | 192 /// * `$data_member` is the identifier of the data member of `$inner_struct` |
193 /// that will be shared. | 193 /// that will be shared. |
194 /// * `$leaked` is the identifier to give to the struct that will manage | 194 /// * `$leaked` is the identifier to give to the struct that will manage |
195 /// references to `$name`, to be used for example in other macros like | 195 /// references to `$name`, to be used for example in other macros like |
196 /// `py_shared_mapping_iterator`. | 196 /// `py_shared_iterator_impl`. |
197 /// | 197 /// |
198 /// # Example | 198 /// # Example |
199 /// | 199 /// |
200 /// ``` | 200 /// ``` |
201 /// struct MyStruct { | 201 /// struct MyStruct { |
281 } | 281 } |
282 }; | 282 }; |
283 } | 283 } |
284 | 284 |
285 /// Defines a `py_class!` that acts as a Python iterator over a Rust iterator. | 285 /// Defines a `py_class!` that acts as a Python iterator over a Rust iterator. |
286 /// | |
287 /// TODO: this is a bit awkward to use, and a better (more complicated) | |
288 /// procedural macro would simplify the interface a lot. | |
289 /// | |
290 /// # Parameters | |
291 /// | |
292 /// * `$name` is the identifier to give to the resulting Rust struct. | |
293 /// * `$leaked` corresponds to `$leaked` in the matching `py_shared_ref!` call. | |
294 /// * `$iterator_type` is the type of the Rust iterator. | |
295 /// * `$success_func` is a function for processing the Rust `(key, value)` | |
296 /// tuple on iteration success, turning it into something Python understands. | |
297 /// * `$success_func` is the return type of `$success_func` | |
298 /// | |
299 /// # Example | |
300 /// | |
301 /// ``` | |
302 /// struct MyStruct { | |
303 /// inner: HashMap<Vec<u8>, Vec<u8>>; | |
304 /// } | |
305 /// | |
306 /// py_class!(pub class MyType |py| { | |
307 /// data inner: PySharedRefCell<MyStruct>; | |
308 /// data py_shared_state: PySharedState; | |
309 /// | |
310 /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> { | |
311 /// let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? }; | |
312 /// MyTypeItemsIterator::create_instance( | |
313 /// py, | |
314 /// RefCell::new(Some(leak_handle)), | |
315 /// RefCell::new(leaked_ref.iter()), | |
316 /// ) | |
317 /// } | |
318 /// }); | |
319 /// | |
320 /// impl MyType { | |
321 /// fn translate_key_value( | |
322 /// py: Python, | |
323 /// res: (&Vec<u8>, &Vec<u8>), | |
324 /// ) -> PyResult<Option<(PyBytes, PyBytes)>> { | |
325 /// let (f, entry) = res; | |
326 /// Ok(Some(( | |
327 /// PyBytes::new(py, f), | |
328 /// PyBytes::new(py, entry), | |
329 /// ))) | |
330 /// } | |
331 /// } | |
332 /// | |
333 /// py_shared_ref!(MyType, MyStruct, inner, MyTypeLeakedRef); | |
334 /// | |
335 /// py_shared_iterator_impl!( | |
336 /// MyTypeItemsIterator, | |
337 /// MyTypeLeakedRef, | |
338 /// HashMap<'static, Vec<u8>, Vec<u8>>, | |
339 /// MyType::translate_key_value, | |
340 /// Option<(PyBytes, PyBytes)> | |
341 /// ); | |
342 /// ``` | |
286 macro_rules! py_shared_iterator_impl { | 343 macro_rules! py_shared_iterator_impl { |
287 ( | 344 ( |
288 $name: ident, | 345 $name: ident, |
289 $leaked: ident, | 346 $leaked: ident, |
290 $iterator_type: ty, | 347 $iterator_type: ty, |
331 ) | 388 ) |
332 } | 389 } |
333 } | 390 } |
334 }; | 391 }; |
335 } | 392 } |
336 | |
337 /// Defines a `py_class!` that acts as a Python mapping iterator over a Rust | |
338 /// iterator. | |
339 /// | |
340 /// TODO: this is a bit awkward to use, and a better (more complicated) | |
341 /// procedural macro would simplify the interface a lot. | |
342 /// | |
343 /// # Parameters | |
344 /// | |
345 /// * `$name` is the identifier to give to the resulting Rust struct. | |
346 /// * `$leaked` corresponds to `$leaked` in the matching `py_shared_ref!` call. | |
347 /// * `$key_type` is the type of the key in the mapping | |
348 /// * `$value_type` is the type of the value in the mapping | |
349 /// * `$success_func` is a function for processing the Rust `(key, value)` | |
350 /// tuple on iteration success, turning it into something Python understands. | |
351 /// * `$success_func` is the return type of `$success_func` | |
352 /// | |
353 /// # Example | |
354 /// | |
355 /// ``` | |
356 /// struct MyStruct { | |
357 /// inner: HashMap<Vec<u8>, Vec<u8>>; | |
358 /// } | |
359 /// | |
360 /// py_class!(pub class MyType |py| { | |
361 /// data inner: PySharedRefCell<MyStruct>; | |
362 /// data py_shared_state: PySharedState; | |
363 /// | |
364 /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> { | |
365 /// let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? }; | |
366 /// MyTypeItemsIterator::create_instance( | |
367 /// py, | |
368 /// RefCell::new(Some(leak_handle)), | |
369 /// RefCell::new(leaked_ref.iter()), | |
370 /// ) | |
371 /// } | |
372 /// }); | |
373 /// | |
374 /// impl MyType { | |
375 /// fn translate_key_value( | |
376 /// py: Python, | |
377 /// res: (&Vec<u8>, &Vec<u8>), | |
378 /// ) -> PyResult<Option<(PyBytes, PyBytes)>> { | |
379 /// let (f, entry) = res; | |
380 /// Ok(Some(( | |
381 /// PyBytes::new(py, f), | |
382 /// PyBytes::new(py, entry), | |
383 /// ))) | |
384 /// } | |
385 /// } | |
386 /// | |
387 /// py_shared_ref!(MyType, MyStruct, inner, MyTypeLeakedRef); | |
388 /// | |
389 /// py_shared_mapping_iterator!( | |
390 /// MyTypeItemsIterator, | |
391 /// MyTypeLeakedRef, | |
392 /// Vec<u8>, | |
393 /// Vec<u8>, | |
394 /// MyType::translate_key_value, | |
395 /// Option<(PyBytes, PyBytes)> | |
396 /// ); | |
397 /// ``` | |
398 #[allow(unused)] // Removed in a future patch | |
399 macro_rules! py_shared_mapping_iterator { | |
400 ( | |
401 $name:ident, | |
402 $leaked:ident, | |
403 $key_type: ty, | |
404 $value_type: ty, | |
405 $success_func: path, | |
406 $success_type: ty | |
407 ) => { | |
408 py_shared_iterator_impl!( | |
409 $name, | |
410 $leaked, | |
411 Box< | |
412 dyn Iterator<Item = (&'static $key_type, &'static $value_type)> | |
413 + Send, | |
414 >, | |
415 $success_func, | |
416 $success_type | |
417 ); | |
418 }; | |
419 } |