I have a collection of images, and an associated collection of views into the former.
Here is some outline code which summarizes the situation:
struct Image;
struct SubImage<'i> {
image: &'i Image,
metadata: u32,
}
fn foo() {
let full_images: Vec<Image> = vec![Image, Image, Image];
let sub_images: Vec<SubImage<'_>> = vec![
SubImage { image: &full_images[0], metadata: 42 }
SubImage { image: &full_images[2], metadata: 666 }
];
}
This is fine as long as sub_images
does not outlive full_images
, and it's trivial for this to work if these two variables live in a function's local scope.
However, I want a set of such images and sub-images to be created in some producer function and returned for use elsewhere. So I'm looking for a way to package them up together, which naively leads to something like this
struct ImageSet {
full_images: Vec<Image>,
sub_images: Vec<SubImage<'_>>,
}
which is a self-referential struct (a no-go in Rust), because elements of sub_images
refer to elements of full_images
via the ref in the SubImage
struct.
An obvious idea to eliminate the self-referential nature of the ImageSet
struct, is to turn SubImage::image
from a ref into an index. However, previously SubImage
had some methods, roughly like
impl SubImage<'_> {
fn render(&self) { ... }
fn tweak_metadata(&mut self) { ... }
}
which enabled the client to treat each sub-image as a self-contained item. Replacing the ref with an index would burden the client with manually maintaining the association between the full images and the sub-images: the original SubImage
knew exactly which Image
it referred to; the new version knows that it refers to the Nth image in some unknown vector of Image
s.
Can you suggest an approach where the client can use the sub-images without having to care about which full images they refer to?