It’s annoying to have to (I think) write something like this in order to implement an efficient iterator newtype over a slice iterator:
#[derive(Clone, Debug)]
pub struct Nodes<'a, H: 'a, T: 'a>(slice::Iter<'a, Node<H, T>>);
impl<'a, H, T> Iterator for Nodes<'a, H, T> {
type Item = &'a Node<H, T>;
fn next(&mut self) -> Option<Self::Item> { self.0.next() }
fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
fn count(self) -> usize { self.0.count() }
fn nth(&mut self, n: usize) -> Option<Self::Item> { self.0.nth(n) }
fn last(self) -> Option<Self::Item> { self.0.last() }
}
impl<'a, H, T> ExactSizeIterator for Nodes<'a, H, T> {
fn len(&self) -> usize { self.0.len() }
}
impl<'a, H, T> DoubleEndedIterator for Nodes<'a, H, T> {
fn next_back(&mut self) -> Option<Self::Item> { self.0.next_back() }
}
(A couple more trait impls to add if you want to be good with nightly Rust.)
It would be much nicer to be able to do it like this:
#[derive(Clone, Debug)]
#[delegate(Iterator, ExactSizeIterator, DoubleEndedIterator)]
pub struct Nodes<'a, H: 'a, T: 'a>(slice::Iter<'a, Node<H, T>>);
For multi-member structures and tuples, the member could be specified with a parameter:
#[delegate(member=inner; Iterator, ExactSizeIterator, DoubleEndedIterator)]
pub struct Nodes<'a, H: 'a, T: 'a> {
inner: slice::Iter<'a, Node<T>>,
foo: H
}
Of course it’s not possible to automagically do it for any trait: Iterator
, for one, has skip()
and similar object-unsafe methods. This is where procedural macros might be able to help. For object-safe traits the compiler might just generate delegation support implicitly.
Delegation has been discussed here before. Has anyone considered using procedural macros for this? Worth an RFC?