gstreamer: Use helper macro to define various fixed size iterators

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1669>
This commit is contained in:
Sebastian Dröge 2025-03-23 13:21:39 +02:00 committed by GStreamer Marge Bot
parent 3a0bcd0b9e
commit 6278d8d1df
6 changed files with 92 additions and 697 deletions

View file

@ -950,121 +950,11 @@ define_meta_iter!(
macro_rules! define_iter(
($name:ident, $typ:ty, $mtyp:ty, $get_item:expr) => {
pub struct $name<'a> {
buffer: $typ,
idx: usize,
n_memory: usize,
}
impl<'a> fmt::Debug for $name<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct(stringify!($name))
.field("buffer", &self.buffer)
.field("idx", &self.idx)
.field("n_memory", &self.n_memory)
.finish()
}
}
impl<'a> $name<'a> {
fn new(buffer: $typ) -> $name<'a> {
skip_assert_initialized!();
let n_memory = buffer.n_memory();
$name {
buffer,
idx: 0,
n_memory,
}
}
}
#[allow(clippy::redundant_closure_call)]
impl<'a> Iterator for $name<'a> {
type Item = $mtyp;
fn next(&mut self) -> Option<Self::Item> {
if self.idx >= self.n_memory {
return None;
}
#[allow(unused_unsafe)]
unsafe {
let item = $get_item(self.buffer, self.idx).unwrap();
self.idx += 1;
Some(item)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.n_memory - self.idx;
(remaining, Some(remaining))
}
fn count(self) -> usize {
self.n_memory - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.n_memory || overflow {
self.idx = self.n_memory;
None
} else {
#[allow(unused_unsafe)]
unsafe {
self.idx = end + 1;
Some($get_item(self.buffer, end).unwrap())
}
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.n_memory {
None
} else {
#[allow(unused_unsafe)]
unsafe {
Some($get_item(self.buffer, self.n_memory - 1).unwrap())
}
}
}
}
#[allow(clippy::redundant_closure_call)]
impl<'a> DoubleEndedIterator for $name<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.idx == self.n_memory {
return None;
}
#[allow(unused_unsafe)]
unsafe {
self.n_memory -= 1;
Some($get_item(self.buffer, self.n_memory).unwrap())
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.n_memory.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.n_memory;
None
} else {
#[allow(unused_unsafe)]
unsafe {
self.n_memory = end - 1;
Some($get_item(self.buffer, self.n_memory).unwrap())
}
}
}
}
impl<'a> ExactSizeIterator for $name<'a> {}
impl<'a> std::iter::FusedIterator for $name<'a> {}
crate::utils::define_fixed_size_iter!(
$name, $typ, $mtyp,
|buffer: &BufferRef| buffer.n_memory() as usize,
$get_item
);
}
);
@ -1072,13 +962,9 @@ define_iter!(
Iter,
&'a BufferRef,
&'a MemoryRef,
|buffer: &BufferRef, idx| {
|buffer: &BufferRef, idx| unsafe {
let ptr = ffi::gst_buffer_peek_memory(buffer.as_mut_ptr(), idx as u32);
if ptr.is_null() {
None
} else {
Some(MemoryRef::from_ptr(ptr as *const ffi::GstMemory))
}
MemoryRef::from_ptr(ptr as *const ffi::GstMemory)
}
);
@ -1086,13 +972,9 @@ define_iter!(
IterMut,
&'a mut BufferRef,
&'a mut MemoryRef,
|buffer: &mut BufferRef, idx| {
|buffer: &mut BufferRef, idx| unsafe {
let ptr = ffi::gst_buffer_peek_memory(buffer.as_mut_ptr(), idx as u32);
if ptr.is_null() {
None
} else {
Some(MemoryRef::from_mut_ptr(ptr))
}
MemoryRef::from_mut_ptr(ptr)
}
);
@ -1157,7 +1039,10 @@ define_iter!(
IterOwned,
&'a BufferRef,
Memory,
|buffer: &BufferRef, idx| { buffer.memory(idx) }
|buffer: &BufferRef, idx| unsafe {
let ptr = ffi::gst_buffer_get_memory(buffer.as_mut_ptr(), idx as u32);
from_glib_full(ptr)
}
);
impl fmt::Debug for Buffer {

View file

@ -245,103 +245,22 @@ impl fmt::Debug for BufferListRef {
macro_rules! define_iter(
($name:ident, $styp:ty, $get_item:expr) => {
#[derive(Debug)]
pub struct $name<'a> {
list: &'a BufferListRef,
idx: usize,
size: usize,
}
impl<'a> $name<'a> {
fn new(list: &'a BufferListRef) -> $name<'a> {
skip_assert_initialized!();
$name {
list,
idx: 0,
size: list.len(),
}
}
}
#[allow(clippy::redundant_closure_call)]
impl<'a> Iterator for $name<'a> {
type Item = $styp;
fn next(&mut self) -> Option<Self::Item> {
if self.idx >= self.size {
return None;
}
let item = $get_item(self.list, self.idx).unwrap();
self.idx += 1;
Some(item)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.size - self.idx;
(remaining, Some(remaining))
}
fn count(self) -> usize {
self.size - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.size || overflow {
self.idx = self.size;
None
} else {
self.idx = end + 1;
Some($get_item(self.list, end).unwrap())
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.size {
None
} else {
Some($get_item(self.list, self.size - 1).unwrap())
}
}
}
#[allow(clippy::redundant_closure_call)]
impl<'a> DoubleEndedIterator for $name<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.idx == self.size {
return None;
}
self.size -= 1;
Some($get_item(self.list, self.size).unwrap())
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.size.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.size;
None
} else {
self.size = end - 1;
Some($get_item(self.list, self.size).unwrap())
}
}
}
impl<'a> ExactSizeIterator for $name<'a> {}
impl<'a> std::iter::FusedIterator for $name<'a> {}
crate::utils::define_fixed_size_iter!(
$name, &'a BufferListRef, $styp,
|collection: &BufferListRef| collection.len(),
$get_item
);
}
);
define_iter!(Iter, &'a BufferRef, |list: &'a BufferListRef, idx| {
list.get(idx)
define_iter!(Iter, &'a BufferRef, |list: &BufferListRef, idx| unsafe {
let ptr = ffi::gst_buffer_list_get(list.as_mut_ptr(), idx as u32);
BufferRef::from_ptr(ptr)
});
define_iter!(IterOwned, Buffer, |list: &BufferListRef, idx| {
list.get_owned(idx)
define_iter!(IterOwned, Buffer, |list: &BufferListRef, idx| unsafe {
let ptr = ffi::gst_buffer_list_get(list.as_mut_ptr(), idx as u32);
from_glib_none(ptr)
});
impl<'a> IntoIterator for &'a BufferListRef {

View file

@ -1076,107 +1076,11 @@ pub enum CapsFilterMapAction {
macro_rules! define_iter(
($name:ident, $typ:ty, $styp:ty, $get_item:expr) => {
#[derive(Debug)]
pub struct $name<'a> {
caps: $typ,
idx: usize,
n_structures: usize,
}
impl<'a> $name<'a> {
fn new(caps: $typ) -> $name<'a> {
skip_assert_initialized!();
let n_structures = caps.size();
$name {
caps,
idx: 0,
n_structures: n_structures as usize,
}
}
}
#[allow(clippy::redundant_closure_call)]
impl<'a> Iterator for $name<'a> {
type Item = $styp;
fn next(&mut self) -> Option<Self::Item> {
if self.idx >= self.n_structures {
return None;
}
unsafe {
let item = $get_item(self.caps, self.idx).unwrap();
self.idx += 1;
Some(item)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.n_structures - self.idx;
(remaining, Some(remaining))
}
fn count(self) -> usize {
self.n_structures - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.n_structures || overflow {
self.idx = self.n_structures;
None
} else {
unsafe {
self.idx = end + 1;
Some($get_item(self.caps, end).unwrap())
}
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.n_structures {
None
} else {
unsafe {
Some($get_item(self.caps, self.n_structures - 1).unwrap())
}
}
}
}
#[allow(clippy::redundant_closure_call)]
impl<'a> DoubleEndedIterator for $name<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.idx == self.n_structures {
return None;
}
self.n_structures -= 1;
unsafe {
Some($get_item(self.caps, self.n_structures).unwrap())
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.n_structures.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.n_structures;
None
} else {
self.n_structures = end - 1;
unsafe {
Some($get_item(self.caps, self.n_structures).unwrap())
}
}
}
}
impl<'a> ExactSizeIterator for $name<'a> {}
impl<'a> std::iter::FusedIterator for $name<'a> {}
crate::utils::define_fixed_size_iter!(
$name, $typ, $styp,
|collection: &CapsRef| collection.size(),
$get_item
);
}
);
@ -1184,62 +1088,44 @@ define_iter!(
Iter,
&'a CapsRef,
&'a StructureRef,
|caps: &CapsRef, idx| {
|caps: &CapsRef, idx| unsafe {
let ptr = ffi::gst_caps_get_structure(caps.as_ptr(), idx as u32);
if ptr.is_null() {
None
} else {
Some(StructureRef::from_glib_borrow(
ptr as *const ffi::GstStructure,
))
}
StructureRef::from_glib_borrow(ptr as *const ffi::GstStructure)
}
);
define_iter!(
IterMut,
&'a mut CapsRef,
&'a mut StructureRef,
|caps: &CapsRef, idx| {
|caps: &mut CapsRef, idx| unsafe {
let ptr = ffi::gst_caps_get_structure(caps.as_ptr(), idx as u32);
if ptr.is_null() {
None
} else {
Some(StructureRef::from_glib_borrow_mut(ptr))
}
StructureRef::from_glib_borrow_mut(ptr)
}
);
define_iter!(
IterFeatures,
&'a CapsRef,
(&'a StructureRef, &'a CapsFeaturesRef),
|caps: &CapsRef, idx| {
|caps: &CapsRef, idx| unsafe {
let ptr1 = ffi::gst_caps_get_structure(caps.as_ptr(), idx as u32);
let ptr2 = ffi::gst_caps_get_features(caps.as_ptr(), idx as u32);
if ptr1.is_null() || ptr2.is_null() {
None
} else {
Some((
StructureRef::from_glib_borrow(ptr1),
CapsFeaturesRef::from_glib_borrow(ptr2),
))
}
(
StructureRef::from_glib_borrow(ptr1),
CapsFeaturesRef::from_glib_borrow(ptr2),
)
}
);
define_iter!(
IterFeaturesMut,
&'a mut CapsRef,
(&'a mut StructureRef, &'a mut CapsFeaturesRef),
|caps: &CapsRef, idx| {
|caps: &mut CapsRef, idx| unsafe {
let ptr1 = ffi::gst_caps_get_structure(caps.as_ptr(), idx as u32);
let ptr2 = ffi::gst_caps_get_features(caps.as_ptr(), idx as u32);
if ptr1.is_null() || ptr2.is_null() {
None
} else {
Some((
StructureRef::from_glib_borrow_mut(ptr1),
CapsFeaturesRef::from_glib_borrow_mut(ptr2),
))
}
(
StructureRef::from_glib_borrow_mut(ptr1),
CapsFeaturesRef::from_glib_borrow_mut(ptr2),
)
}
);

View file

@ -654,140 +654,16 @@ impl glib::value::ToValueOptional for CapsFeaturesRef {
}
}
#[derive(Debug)]
pub struct Iter<'a> {
caps_features: &'a CapsFeaturesRef,
idx: usize,
n_features: usize,
}
impl<'a> Iter<'a> {
fn new(caps_features: &'a CapsFeaturesRef) -> Iter<'a> {
skip_assert_initialized!();
let n_features = caps_features.size();
Iter {
caps_features,
idx: 0,
n_features,
}
crate::utils::define_fixed_size_iter!(
Iter,
&'a CapsFeaturesRef,
&'a glib::GStr,
|collection: &CapsFeaturesRef| collection.size(),
|collection: &CapsFeaturesRef, idx: usize| unsafe {
let feature = ffi::gst_caps_features_get_nth(collection.as_ptr(), idx as u32);
glib::GStr::from_ptr(feature)
}
}
impl<'a> Iterator for Iter<'a> {
type Item = &'a glib::GStr;
fn next(&mut self) -> Option<Self::Item> {
if self.idx >= self.n_features {
return None;
}
unsafe {
let feature =
ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), self.idx as u32);
debug_assert!(!feature.is_null());
self.idx += 1;
// Safety: we can return a GStr based on the feature here because the lifetime
// of the returned Item is constrained by the underlying CapsFeatureRef.
Some(glib::GStr::from_ptr(feature))
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.n_features - self.idx;
(remaining, Some(remaining))
}
fn count(self) -> usize {
self.n_features - self.idx
}
// checker-ignore-item
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.n_features || overflow {
self.idx = self.n_features;
None
} else {
unsafe {
self.idx = end + 1;
let feature =
ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), end as u32);
debug_assert!(!feature.is_null());
// Safety: we can return a GStr based on the feature here because the lifetime
// of the returned Item is constrained by the underlying CapsFeatureRef.
Some(glib::GStr::from_ptr(feature))
}
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.n_features {
None
} else {
unsafe {
let feature = ffi::gst_caps_features_get_nth(
self.caps_features.as_ptr(),
self.n_features as u32 - 1,
);
debug_assert!(!feature.is_null());
// Safety: we can return a GStr based on the feature here because the lifetime
// of the returned Item is constrained by the underlying CapsFeatureRef.
Some(glib::GStr::from_ptr(feature))
}
}
}
}
impl DoubleEndedIterator for Iter<'_> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.idx == self.n_features {
return None;
}
self.n_features -= 1;
unsafe {
let feature =
ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), self.n_features as u32);
debug_assert!(!feature.is_null());
// Safety: we can return a GStr based on the feature here because the lifetime
// of the returned Item is constrained by the underlying CapsFeatureRef.
Some(glib::GStr::from_ptr(feature))
}
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.n_features.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.n_features;
None
} else {
unsafe {
self.n_features = end - 1;
let feature = ffi::gst_caps_features_get_nth(
self.caps_features.as_ptr(),
self.n_features as u32,
);
debug_assert!(!feature.is_null());
// Safety: we can return a GStr based on the feature here because the lifetime
// of the returned Item is constrained by the underlying CapsFeatureRef.
Some(glib::GStr::from_ptr(feature))
}
}
}
}
impl ExactSizeIterator for Iter<'_> {}
impl std::iter::FusedIterator for Iter<'_> {}
);
impl<'a> IntoIterator for &'a CapsFeaturesRef {
type IntoIter = Iter<'a>;

View file

@ -10,93 +10,18 @@ use glib::{
use crate::{ffi, Stream, StreamCollection};
#[derive(Debug)]
pub struct Iter<'a> {
collection: &'a StreamCollection,
idx: usize,
size: usize,
}
impl<'a> Iter<'a> {
fn new(collection: &'a StreamCollection) -> Iter<'a> {
skip_assert_initialized!();
Iter {
collection,
idx: 0,
size: collection.len(),
}
crate::utils::define_fixed_size_iter!(
Iter,
&'a StreamCollection,
Stream,
|collection: &StreamCollection| collection.len(),
|collection: &StreamCollection, idx: usize| unsafe {
from_glib_none(ffi::gst_stream_collection_get_stream(
collection.to_glib_none().0,
idx as u32,
))
}
}
impl Iterator for Iter<'_> {
type Item = Stream;
fn next(&mut self) -> Option<Self::Item> {
if self.idx >= self.size {
return None;
}
let item = self.collection.stream(self.idx as u32).unwrap();
self.idx += 1;
Some(item)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.size - self.idx;
(remaining, Some(remaining))
}
fn count(self) -> usize {
self.size - self.idx
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.idx.overflowing_add(n);
if end >= self.size || overflow {
self.idx = self.size;
None
} else {
self.idx = end + 1;
Some(self.collection.stream(end as u32).unwrap())
}
}
fn last(self) -> Option<Self::Item> {
if self.idx == self.size {
None
} else {
Some(self.collection.stream(self.size as u32 - 1).unwrap())
}
}
}
impl DoubleEndedIterator for Iter<'_> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.idx == self.size {
return None;
}
self.size -= 1;
Some(self.collection.stream(self.size as u32).unwrap())
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let (end, overflow) = self.size.overflowing_sub(n);
if end <= self.idx || overflow {
self.idx = self.size;
None
} else {
self.size = end - 1;
Some(self.collection.stream(self.size as u32).unwrap())
}
}
}
impl ExactSizeIterator for Iter<'_> {}
impl std::iter::FusedIterator for Iter<'_> {}
);
#[derive(Debug, Clone)]
#[must_use = "The builder must be built to be used"]

View file

@ -1755,126 +1755,30 @@ impl glib::value::ToValueOptional for StructureRef {
}
}
#[derive(Debug)]
pub struct FieldIterator<'a> {
structure: &'a StructureRef,
idx: usize,
n_fields: usize,
}
impl<'a> FieldIterator<'a> {
fn new(structure: &'a StructureRef) -> FieldIterator<'a> {
skip_assert_initialized!();
let n_fields = structure.n_fields();
FieldIterator {
structure,
idx: 0,
n_fields,
}
crate::utils::define_fixed_size_iter!(
FieldIterator,
&'a StructureRef,
&'a glib::GStr,
|collection: &StructureRef| collection.n_fields(),
|collection: &StructureRef, idx: usize| unsafe {
let field_name = ffi::gst_structure_nth_field_name(&collection.0, idx as u32);
glib::GStr::from_ptr(field_name)
}
}
impl<'a> Iterator for FieldIterator<'a> {
type Item = &'a glib::GStr;
fn next(&mut self) -> Option<Self::Item> {
if self.idx >= self.n_fields {
return None;
}
let field_name = self.structure.nth_field_name(self.idx).unwrap();
self.idx += 1;
Some(field_name)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.n_fields - self.idx;
(remaining, Some(remaining))
}
}
impl DoubleEndedIterator for FieldIterator<'_> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.idx == self.n_fields {
return None;
}
self.n_fields -= 1;
// Safety: nth_field_name() ensures static lifetime for the returned string,
// whatever the GStreamer version being used.
Some(self.structure.nth_field_name(self.n_fields).unwrap())
}
}
impl ExactSizeIterator for FieldIterator<'_> {}
impl std::iter::FusedIterator for FieldIterator<'_> {}
);
#[cfg(feature = "v1_26")]
#[derive(Debug)]
pub struct FieldIdIterator<'a> {
structure: &'a StructureRef,
idx: usize,
n_fields: usize,
}
crate::utils::define_fixed_size_iter!(
FieldIdIterator,
&'a StructureRef,
&'a crate::IdStr,
|collection: &StructureRef| collection.n_fields(),
|collection: &StructureRef, idx: usize| unsafe {
let field_name = ffi::gst_structure_id_str_nth_field_name(&collection.0, idx as u32);
debug_assert!(!field_name.is_null());
#[cfg(feature = "v1_26")]
impl<'a> FieldIdIterator<'a> {
fn new(structure: &'a StructureRef) -> FieldIdIterator<'a> {
skip_assert_initialized!();
let n_fields = structure.n_fields();
FieldIdIterator {
structure,
idx: 0,
n_fields,
}
&*(field_name as *const crate::IdStr)
}
}
#[cfg(feature = "v1_26")]
impl<'a> Iterator for FieldIdIterator<'a> {
type Item = &'a IdStr;
fn next(&mut self) -> Option<Self::Item> {
if self.idx >= self.n_fields {
return None;
}
let field_name = self.structure.nth_field_by_id(self.idx).unwrap();
self.idx += 1;
Some(field_name)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.n_fields - self.idx;
(remaining, Some(remaining))
}
}
#[cfg(feature = "v1_26")]
impl DoubleEndedIterator for FieldIdIterator<'_> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.idx == self.n_fields {
return None;
}
self.n_fields -= 1;
// Safety: nth_field_name() ensures static lifetime for the returned string,
// whatever the GStreamer version being used.
Some(self.structure.nth_field_by_id(self.n_fields).unwrap())
}
}
#[cfg(feature = "v1_26")]
impl ExactSizeIterator for FieldIdIterator<'_> {}
#[cfg(feature = "v1_26")]
impl std::iter::FusedIterator for FieldIdIterator<'_> {}
);
#[derive(Debug)]
pub struct Iter<'a> {
@ -1895,7 +1799,7 @@ impl<'a> Iterator for Iter<'a> {
fn next(&mut self) -> Option<Self::Item> {
let f = self.iter.next()?;
let v = self.iter.structure.value(f);
let v = self.iter.collection.value(f);
Some((f, v.unwrap()))
}
@ -1909,12 +1813,12 @@ impl<'a> Iterator for Iter<'a> {
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let f = self.iter.nth(n)?;
let v = self.iter.structure.value(f);
let v = self.iter.collection.value(f);
Some((f, v.unwrap()))
}
fn last(self) -> Option<Self::Item> {
let structure = self.iter.structure;
let structure = self.iter.collection;
let f = self.iter.last()?;
let v = structure.value(f);
Some((f, v.unwrap()))
@ -1924,13 +1828,13 @@ impl<'a> Iterator for Iter<'a> {
impl DoubleEndedIterator for Iter<'_> {
fn next_back(&mut self) -> Option<Self::Item> {
let f = self.iter.next_back()?;
let v = self.iter.structure.value(f);
let v = self.iter.collection.value(f);
Some((f, v.unwrap()))
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let f = self.iter.nth_back(n)?;
let v = self.iter.structure.value(f);
let v = self.iter.collection.value(f);
Some((f, v.unwrap()))
}
}
@ -1961,7 +1865,7 @@ impl<'a> Iterator for IdIter<'a> {
fn next(&mut self) -> Option<Self::Item> {
let f = self.iter.next()?;
let v = self.iter.structure.value_by_id(f);
let v = self.iter.collection.value_by_id(f);
Some((f, v.unwrap()))
}
@ -1975,12 +1879,12 @@ impl<'a> Iterator for IdIter<'a> {
fn nth(&mut self, n: usize) -> Option<Self::Item> {
let f = self.iter.nth(n)?;
let v = self.iter.structure.value_by_id(f);
let v = self.iter.collection.value_by_id(f);
Some((f, v.unwrap()))
}
fn last(self) -> Option<Self::Item> {
let structure = self.iter.structure;
let structure = self.iter.collection;
let f = self.iter.last()?;
let v = structure.value_by_id(f);
Some((f, v.unwrap()))
@ -1991,13 +1895,13 @@ impl<'a> Iterator for IdIter<'a> {
impl DoubleEndedIterator for IdIter<'_> {
fn next_back(&mut self) -> Option<Self::Item> {
let f = self.iter.next_back()?;
let v = self.iter.structure.value_by_id(f);
let v = self.iter.collection.value_by_id(f);
Some((f, v.unwrap()))
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let f = self.iter.nth_back(n)?;
let v = self.iter.structure.value_by_id(f);
let v = self.iter.collection.value_by_id(f);
Some((f, v.unwrap()))
}
}