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 }