Skip to content

Commit

Permalink
Implement more iterators
Browse files Browse the repository at this point in the history
Also change `to_str_tuple(…)` in order to share more code between two of
the iterators.

Suggested-by: Alex Crichton <alex@alexcrichton.com>
See: #749 (comment)
  • Loading branch information
LemmingAvalanche committed Oct 14, 2021
1 parent 55ea909 commit e7b0306
Showing 1 changed file with 27 additions and 12 deletions.
39 changes: 27 additions & 12 deletions src/message.rs
Expand Up @@ -98,22 +98,37 @@ impl<'pair> Iterator for MessageTrailersIterator<'pair> {
type Item = (&'pair str, &'pair str);

fn next(&mut self) -> Option<Self::Item> {
self.range.next().map(|index| unsafe {
let addr = self.trailers.raw.trailers.wrapping_add(index);
to_str_tuple((*addr).key, (*addr).value, marker::PhantomData)
})
self.range
.next()
.map(|index| to_str_tuple(&self.trailers, index, marker::PhantomData))
}
}

fn to_str_tuple<'pair>(
key: *const c_char,
value: *const c_char,
_marker: marker::PhantomData<&'pair c_char>,
) -> (&'pair str, &'pair str) {
#[inline(always)]
fn to_str_tuple(
trailers: &MessageTrailers,
index: usize,
_marker: marker::PhantomData<c_char>,
) -> (&str, &str) {
unsafe {
let k = CStr::from_ptr(key).to_str().unwrap();
let v = CStr::from_ptr(value).to_str().unwrap();
(k, v)
let addr = trailers.raw.trailers.wrapping_add(index);
let key = CStr::from_ptr((*addr).key).to_str().unwrap();
let value = CStr::from_ptr((*addr).value).to_str().unwrap();
(key, value)
}
}

impl ExactSizeIterator for MessageTrailersIterator<'_> {
fn len(&self) -> usize {
self.range.end
}
}

impl DoubleEndedIterator for MessageTrailersIterator<'_> {
fn next_back(&mut self) -> Option<Self::Item> {
self.range
.next_back()
.map(|index| to_str_tuple(&self.trailers, index, marker::PhantomData))
}
}

Expand Down

0 comments on commit e7b0306

Please sign in to comment.