# HG changeset patch # User Yuya Nishihara # Date 1567912998 -32400 # Node ID 67853749961b40a5ac97f310b49f19e5a530fccc # Parent 706104dcb2c84352b198bb94416b28f93461ceba rust-cpython: replace dyn Iterator<..> of mapping with concrete type See the previous commit for why. The docstring is moved accordingly. diff -r 706104dcb2c8 -r 67853749961b rust/hg-cpython/src/dirstate/copymap.rs --- a/rust/hg-cpython/src/dirstate/copymap.rs Sun Sep 08 12:07:19 2019 +0900 +++ b/rust/hg-cpython/src/dirstate/copymap.rs Sun Sep 08 12:23:18 2019 +0900 @@ -12,6 +12,7 @@ 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 @@ } } -py_shared_mapping_iterator!( +py_shared_iterator_impl!( CopyMapKeysIterator, DirstateMapLeakedRef, - Vec, - Vec, + CopyMapIter<'static>, CopyMap::translate_key, Option ); -py_shared_mapping_iterator!( +py_shared_iterator_impl!( CopyMapItemsIterator, DirstateMapLeakedRef, - Vec, - Vec, + CopyMapIter<'static>, CopyMap::translate_key_value, Option<(PyBytes, PyBytes)> ); diff -r 706104dcb2c8 -r 67853749961b rust/hg-cpython/src/dirstate/dirstate_map.rs --- a/rust/hg-cpython/src/dirstate/dirstate_map.rs Sun Sep 08 12:07:19 2019 +0900 +++ b/rust/hg-cpython/src/dirstate/dirstate_map.rs Sun Sep 08 12:23:18 2019 +0900 @@ -25,7 +25,8 @@ }; use hg::{ DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap, - DirstateParents, DirstateParseError, EntryState, PARENT_SIZE, + DirstateParents, DirstateParseError, EntryState, StateMapIter, + PARENT_SIZE, }; // TODO @@ -323,7 +324,7 @@ DirstateMapKeysIterator::from_inner( py, Some(leak_handle), - Box::new(leaked_ref.iter()), + leaked_ref.iter(), ) } @@ -332,7 +333,7 @@ DirstateMapItemsIterator::from_inner( py, Some(leak_handle), - Box::new(leaked_ref.iter()), + leaked_ref.iter(), ) } @@ -341,7 +342,7 @@ DirstateMapKeysIterator::from_inner( py, Some(leak_handle), - Box::new(leaked_ref.iter()), + leaked_ref.iter(), ) } @@ -438,7 +439,7 @@ CopyMapKeysIterator::from_inner( py, Some(leak_handle), - Box::new(leaked_ref.copy_map.iter()), + leaked_ref.copy_map.iter(), ) } @@ -447,7 +448,7 @@ CopyMapItemsIterator::from_inner( py, Some(leak_handle), - Box::new(leaked_ref.copy_map.iter()), + leaked_ref.copy_map.iter(), ) } @@ -483,20 +484,18 @@ py_shared_ref!(DirstateMap, RustDirstateMap, inner, DirstateMapLeakedRef,); -py_shared_mapping_iterator!( +py_shared_iterator_impl!( DirstateMapKeysIterator, DirstateMapLeakedRef, - Vec, - DirstateEntry, + StateMapIter<'static>, DirstateMap::translate_key, Option ); -py_shared_mapping_iterator!( +py_shared_iterator_impl!( DirstateMapItemsIterator, DirstateMapLeakedRef, - Vec, - DirstateEntry, + StateMapIter<'static>, DirstateMap::translate_key_value, Option<(PyBytes, PyObject)> ); diff -r 706104dcb2c8 -r 67853749961b rust/hg-cpython/src/ref_sharing.rs --- a/rust/hg-cpython/src/ref_sharing.rs Sun Sep 08 12:07:19 2019 +0900 +++ b/rust/hg-cpython/src/ref_sharing.rs Sun Sep 08 12:23:18 2019 +0900 @@ -193,7 +193,7 @@ /// 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 @@ } /// 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>; +/// } +/// +/// py_class!(pub class MyType |py| { +/// data inner: PySharedRefCell; +/// data py_shared_state: PySharedState; +/// +/// def __iter__(&self) -> PyResult { +/// 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, &Vec), +/// ) -> PyResult> { +/// 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, Vec>, +/// MyType::translate_key_value, +/// Option<(PyBytes, PyBytes)> +/// ); +/// ``` macro_rules! py_shared_iterator_impl { ( $name: ident, @@ -333,87 +390,3 @@ } }; } - -/// 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>; -/// } -/// -/// py_class!(pub class MyType |py| { -/// data inner: PySharedRefCell; -/// data py_shared_state: PySharedState; -/// -/// def __iter__(&self) -> PyResult { -/// 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, &Vec), -/// ) -> PyResult> { -/// 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, -/// Vec, -/// 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 - + Send, - >, - $success_func, - $success_type - ); - }; -}