Patchwork [4,of,7] rust-cpython: replace dyn Iterator<..> of mapping with concrete type

login
register
mail settings
Submitter Yuya Nishihara
Date Sept. 8, 2019, 10:05 a.m.
Message ID <21e85ee4785728c37823.1567937144@mimosa>
Download mbox | patch
Permalink /patch/41574/
State Accepted
Headers show

Comments

Yuya Nishihara - Sept. 8, 2019, 10:05 a.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1567912998 -32400
#      Sun Sep 08 12:23:18 2019 +0900
# Node ID 21e85ee4785728c37823d3b3fc70b89beec4fb63
# Parent  3c707d5a55e140de8117893a142c2b17f1a7f401
rust-cpython: replace dyn Iterator<..> of mapping with concrete type

See the previous commit for why. The docstring is moved accordingly.

Patch

diff --git a/rust/hg-cpython/src/dirstate/copymap.rs b/rust/hg-cpython/src/dirstate/copymap.rs
--- a/rust/hg-cpython/src/dirstate/copymap.rs
+++ b/rust/hg-cpython/src/dirstate/copymap.rs
@@ -12,6 +12,7 @@  use cpython::{PyBytes, PyClone, PyDict, 
 use std::cell::RefCell;
 
 use crate::dirstate::dirstate_map::{DirstateMap, DirstateMapLeakedRef};
+use hg::CopyMapIter;
 
 py_class!(pub class CopyMap |py| {
     data dirstate_map: DirstateMap;
@@ -97,20 +98,18 @@  impl CopyMap {
     }
 }
 
-py_shared_mapping_iterator!(
+py_shared_iterator_impl!(
     CopyMapKeysIterator,
     DirstateMapLeakedRef,
-    Vec<u8>,
-    Vec<u8>,
+    CopyMapIter<'static>,
     CopyMap::translate_key,
     Option<PyBytes>
 );
 
-py_shared_mapping_iterator!(
+py_shared_iterator_impl!(
     CopyMapItemsIterator,
     DirstateMapLeakedRef,
-    Vec<u8>,
-    Vec<u8>,
+    CopyMapIter<'static>,
     CopyMap::translate_key_value,
     Option<(PyBytes, PyBytes)>
 );
diff --git a/rust/hg-cpython/src/dirstate/dirstate_map.rs b/rust/hg-cpython/src/dirstate/dirstate_map.rs
--- a/rust/hg-cpython/src/dirstate/dirstate_map.rs
+++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs
@@ -25,7 +25,8 @@  use crate::{
 };
 use hg::{
     DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap,
-    DirstateParents, DirstateParseError, EntryState, PARENT_SIZE,
+    DirstateParents, DirstateParseError, EntryState, StateMapIter,
+    PARENT_SIZE,
 };
 
 // TODO
@@ -323,7 +324,7 @@  py_class!(pub class DirstateMap |py| {
         DirstateMapKeysIterator::from_inner(
             py,
             Some(leak_handle),
-            Box::new(leaked_ref.iter()),
+            leaked_ref.iter(),
         )
     }
 
@@ -332,7 +333,7 @@  py_class!(pub class DirstateMap |py| {
         DirstateMapItemsIterator::from_inner(
             py,
             Some(leak_handle),
-            Box::new(leaked_ref.iter()),
+            leaked_ref.iter(),
         )
     }
 
@@ -341,7 +342,7 @@  py_class!(pub class DirstateMap |py| {
         DirstateMapKeysIterator::from_inner(
             py,
             Some(leak_handle),
-            Box::new(leaked_ref.iter()),
+            leaked_ref.iter(),
         )
     }
 
@@ -438,7 +439,7 @@  py_class!(pub class DirstateMap |py| {
         CopyMapKeysIterator::from_inner(
             py,
             Some(leak_handle),
-            Box::new(leaked_ref.copy_map.iter()),
+            leaked_ref.copy_map.iter(),
         )
     }
 
@@ -447,7 +448,7 @@  py_class!(pub class DirstateMap |py| {
         CopyMapItemsIterator::from_inner(
             py,
             Some(leak_handle),
-            Box::new(leaked_ref.copy_map.iter()),
+            leaked_ref.copy_map.iter(),
         )
     }
 
@@ -483,20 +484,18 @@  impl DirstateMap {
 
 py_shared_ref!(DirstateMap, RustDirstateMap, inner, DirstateMapLeakedRef,);
 
-py_shared_mapping_iterator!(
+py_shared_iterator_impl!(
     DirstateMapKeysIterator,
     DirstateMapLeakedRef,
-    Vec<u8>,
-    DirstateEntry,
+    StateMapIter<'static>,
     DirstateMap::translate_key,
     Option<PyBytes>
 );
 
-py_shared_mapping_iterator!(
+py_shared_iterator_impl!(
     DirstateMapItemsIterator,
     DirstateMapLeakedRef,
-    Vec<u8>,
-    DirstateEntry,
+    StateMapIter<'static>,
     DirstateMap::translate_key_value,
     Option<(PyBytes, PyObject)>
 );
diff --git a/rust/hg-cpython/src/ref_sharing.rs b/rust/hg-cpython/src/ref_sharing.rs
--- a/rust/hg-cpython/src/ref_sharing.rs
+++ b/rust/hg-cpython/src/ref_sharing.rs
@@ -193,7 +193,7 @@  impl<'a, T> Drop for PyRefMut<'a, T> {
 /// that will be shared.
 /// * `$leaked` is the identifier to give to the struct that will manage
 /// references to `$name`, to be used for example in other macros like
-/// `py_shared_mapping_iterator`.
+/// `py_shared_iterator_impl`.
 ///
 /// # Example
 ///
@@ -283,6 +283,63 @@  macro_rules! py_shared_ref {
 }
 
 /// Defines a `py_class!` that acts as a Python iterator over a Rust iterator.
+///
+/// TODO: this is a bit awkward to use, and a better (more complicated)
+///     procedural macro would simplify the interface a lot.
+///
+/// # Parameters
+///
+/// * `$name` is the identifier to give to the resulting Rust struct.
+/// * `$leaked` corresponds to `$leaked` in the matching `py_shared_ref!` call.
+/// * `$iterator_type` is the type of the Rust iterator.
+/// * `$success_func` is a function for processing the Rust `(key, value)`
+/// tuple on iteration success, turning it into something Python understands.
+/// * `$success_func` is the return type of `$success_func`
+///
+/// # Example
+///
+/// ```
+/// struct MyStruct {
+///     inner: HashMap<Vec<u8>, Vec<u8>>;
+/// }
+///
+/// py_class!(pub class MyType |py| {
+///     data inner: PySharedRefCell<MyStruct>;
+///     data py_shared_state: PySharedState;
+///
+///     def __iter__(&self) -> PyResult<MyTypeItemsIterator> {
+///         let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
+///         MyTypeItemsIterator::create_instance(
+///             py,
+///             RefCell::new(Some(leak_handle)),
+///             RefCell::new(leaked_ref.iter()),
+///         )
+///     }
+/// });
+///
+/// impl MyType {
+///     fn translate_key_value(
+///         py: Python,
+///         res: (&Vec<u8>, &Vec<u8>),
+///     ) -> PyResult<Option<(PyBytes, PyBytes)>> {
+///         let (f, entry) = res;
+///         Ok(Some((
+///             PyBytes::new(py, f),
+///             PyBytes::new(py, entry),
+///         )))
+///     }
+/// }
+///
+/// py_shared_ref!(MyType, MyStruct, inner, MyTypeLeakedRef);
+///
+/// py_shared_iterator_impl!(
+///     MyTypeItemsIterator,
+///     MyTypeLeakedRef,
+///     HashMap<'static, Vec<u8>, Vec<u8>>,
+///     MyType::translate_key_value,
+///     Option<(PyBytes, PyBytes)>
+/// );
+/// ```
 macro_rules! py_shared_iterator_impl {
     (
         $name: ident,
@@ -333,87 +390,3 @@  macro_rules! py_shared_iterator_impl {
         }
     };
 }
-
-/// Defines a `py_class!` that acts as a Python mapping iterator over a Rust
-/// iterator.
-///
-/// TODO: this is a bit awkward to use, and a better (more complicated)
-///     procedural macro would simplify the interface a lot.
-///
-/// # Parameters
-///
-/// * `$name` is the identifier to give to the resulting Rust struct.
-/// * `$leaked` corresponds to `$leaked` in the matching `py_shared_ref!` call.
-/// * `$key_type` is the type of the key in the mapping
-/// * `$value_type` is the type of the value in the mapping
-/// * `$success_func` is a function for processing the Rust `(key, value)`
-/// tuple on iteration success, turning it into something Python understands.
-/// * `$success_func` is the return type of `$success_func`
-///
-/// # Example
-///
-/// ```
-/// struct MyStruct {
-///     inner: HashMap<Vec<u8>, Vec<u8>>;
-/// }
-///
-/// py_class!(pub class MyType |py| {
-///     data inner: PySharedRefCell<MyStruct>;
-///     data py_shared_state: PySharedState;
-///
-///     def __iter__(&self) -> PyResult<MyTypeItemsIterator> {
-///         let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
-///         MyTypeItemsIterator::create_instance(
-///             py,
-///             RefCell::new(Some(leak_handle)),
-///             RefCell::new(leaked_ref.iter()),
-///         )
-///     }
-/// });
-///
-/// impl MyType {
-///     fn translate_key_value(
-///         py: Python,
-///         res: (&Vec<u8>, &Vec<u8>),
-///     ) -> PyResult<Option<(PyBytes, PyBytes)>> {
-///         let (f, entry) = res;
-///         Ok(Some((
-///             PyBytes::new(py, f),
-///             PyBytes::new(py, entry),
-///         )))
-///     }
-/// }
-///
-/// py_shared_ref!(MyType, MyStruct, inner, MyTypeLeakedRef);
-///
-/// py_shared_mapping_iterator!(
-///     MyTypeItemsIterator,
-///     MyTypeLeakedRef,
-///     Vec<u8>,
-///     Vec<u8>,
-///     MyType::translate_key_value,
-///     Option<(PyBytes, PyBytes)>
-/// );
-/// ```
-#[allow(unused)] // Removed in a future patch
-macro_rules! py_shared_mapping_iterator {
-    (
-        $name:ident,
-        $leaked:ident,
-        $key_type: ty,
-        $value_type: ty,
-        $success_func: path,
-        $success_type: ty
-    ) => {
-        py_shared_iterator_impl!(
-            $name,
-            $leaked,
-            Box<
-                dyn Iterator<Item = (&'static $key_type, &'static $value_type)>
-                    + Send,
-            >,
-            $success_func,
-            $success_type
-        );
-    };
-}