I want to create safe interface in Rust for a C library. That library provides a generator function which can be called multiple times on some source (eg. file) pointer yielding pointers to subsequent elements of that source - basically it's an iterator.
Some useful things can be done with that element pointer, but after the generator function is called again the previous pointer becomes invalid. The element can also be safely cloned (which is what I'm using now) but that comes with significant performance penalty, which in many use cases is completely unnecessary.
I want to create a safe wrapper interface similar to the C interface. My current idea is that I wrap element pointer in struct Element
and source pointer with struct Source
that also holds currently valid Element
.
struct Source {
current_element: Element,
source_pointer: *mut S,
}
// things can be done with &Element directly
// or it can be safely cloned to Element
struct Element {
element_pointer: *mut E,
}
To wrap that generator behavior, I want to implement Iterator
for Source
that in each iteration generates new element_pointer, wraps it, assigns to Source
and returns reference to current_element
that is valid only until .next()
is again called. Something like this:
impl Iterator for Source {
type Item = &Wrapper;
fn next(&mut self) -> Option<Self::Item> {
let new_pointer = unsafe{generator_ffi_function(self.source_pointer)};
if new_pointer.is_null() {
None
} else {
self.current_wrapper.element_pointer = new_pointer;
Some(&self.current_wrapper)
}
}
}
But I cannot solve how to use lifetimes in this scenario. Can the intended interface be implemented in Rust, and if so how?
This solution does not work, because when string_holder
being &'a mut
breaks things. This example wraps similar C interface, but returns pointers so isn't safe. Many questions also refer to implementing mutable iterator but I don't want to give &mut
, and those solutions also assume that only one reference exists, which I cannot assure.
Iterator
is not feasible.