rust-cpython: replace dyn Iterator<..> of mapping with concrete type
See the previous commit for why. The docstring is moved accordingly.
--- 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<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)>
);
--- 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<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)>
);
--- 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<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 @@
}
};
}
-
-/// 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
- );
- };
-}