Trying to use ouroboros
in my code, I met this issue: the second struct hasn't accessor for feature_iterator
field.
I can't see why, because other things are equal.
Full source code, and expanded code.
What am I doing wrong?
// this has accessors for all fields
#[self_referencing]
pub struct FgbDriver {
fp: File,
#[borrows(mut fp)]
#[covariant]
features_selected: FgbReader<'this, File, FeaturesSelectedSeek>,
}
// this has no accessors for feature_iterator
#[self_referencing]
pub struct GpkgDriver {
pub feature_iterator: OwnedFeatureIterator,
#[borrows(mut feature_iterator)]
#[covariant]
current_feature: Option<GdalFeature<'this>>,
}
Adding/removing pub
before feature_iterator
makes no difference.
FgbDriver
won’t have an accessor for fp
either.
1 Like
Here’s (the mockup of) a possible solution
use std::error::Error;
use ouroboros::self_referencing;
struct OwnedFeatureIterator;
impl<'a> Iterator for &'a mut OwnedFeatureIterator
where
Self: 'a,
{
type Item = Feature<'a>;
fn next(&mut self) -> Option<Self::Item> {
todo!()
}
}
struct Feature<'a>(&'a ());
#[self_referencing]
pub struct GpkgDriver {
feature_iterator: OwnedFeatureIterator,
#[borrows(mut feature_iterator)]
#[covariant]
inner: GpkgDriverInner<'this>,
}
struct GpkgDriverInner<'a> {
feature_iterator_ref: &'a mut OwnedFeatureIterator,
current_feature: Option<Feature<'a>>,
}
impl<'a> GpkgDriver {
fn forward(&mut self) -> Result<bool, Box<dyn Error>> {
self.with_inner_mut(|inner| {
if let Some(f) = inner.feature_iterator_ref.next() {
inner.current_feature.replace(f);
Ok(true)
} else {
Ok(false)
}
})
}
}
1 Like
Alternative approach, might be nicer looking:
use std::error::Error;
use ouroboros::self_referencing;
struct OwnedFeatureIterator;
impl<'a> Iterator for &'a mut OwnedFeatureIterator
where
Self: 'a,
{
type Item = Feature<'a>;
fn next(&mut self) -> Option<Self::Item> {
todo!()
}
}
struct Feature<'a>(&'a ());
#[self_referencing]
pub struct GpkgDriver {
feature_iterator: OwnedFeatureIterator,
#[borrows(mut feature_iterator)]
feature_iterator_ref: &'this mut OwnedFeatureIterator,
#[borrows()] // needs to borrow nothing initially: set to `None` on construction, populate later
#[covariant]
current_feature: Option<Feature<'this>>,
}
impl<'a> GpkgDriver {
fn forward(&mut self) -> Result<bool, Box<dyn Error>> {
self.with_mut(|mut this| {
if let Some(f) = this.feature_iterator_ref.next() {
this.current_feature.replace(f);
Ok(true)
} else {
Ok(false)
}
})
}
}
1 Like
system
Closed
5
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.