#Trying to abstract away from library types

17 messages · Page 1 of 1 (latest)

prime patio
#

I thought I understood lifetimes

pub struct Waveform<'a, MutSlice, Img: 'a, B>
where 
    MutSlice: DerefMut<Target=[u8]> + 'a,
    B: Fn(&'a mut Img) -> MutSlice,
{

I do not understand lifetimes

I'm trying to write something that abstracts away from the types used by a library by using generics. Problem is I have a type (Img) from which I would like to borrow some bytes (&mut [u8]) in a manner that does not require knowing what Img is (hence closure B). I can't borrow the bytes directly from Img in B though, I can only get an owned type that implements DerefMut<Target=[u8]> that encapsulates some borrowed state from Img. I tried adding lifetimes to express that I only want my mutable slice as long as I can have a mutable reference to Img, but I get

damnit I have to go to work now why must life be so cruel. Please infer the question I'm attempting to ask

shadow shoal
#

🔮

#

My question inference is limited

#

My guess is that you probably want to get rid of that 'a lifetime entirely

#
pub struct Waveform<MutSlice, Img, B>
where 
    MutSlice: DerefMut<Target=[u8]>
    B: Fn(&mut Img) -> MutSlice,
#

At which point lifetime elision kicks in and you end up with the equivalent of B: for<'a> Fn(&'a mut Img) -> MutSlice

stone egret
#

Problem is I have a type (Img) from which I would like to borrow some bytes (&mut [u8]) in a manner that does not require knowing what Img is (hence closure B). I can't borrow the bytes directly from Img in B though, I can only get an owned type that implements DerefMut<Target=[u8]> that encapsulates some borrowed state from Img.
My question inference (intuition) tells me you might just want to make a trait for this and then go from there.
May I ask what you're actually storing in this struct?

steel cape
#

which is a much harder question

stone egret
#

I'm guessing this should be its own trait like

trait BorrowBytesMut {
    type BytesMut<'a>: DerefMut<[u8]>;

    fn borrow_bytes_mut(&mut self) -> BytesMut<'a>;
}
prime patio
#

Sorry I haven't been able to reply, been down with Covid and haven't been able to thonk about programming for days

prime patio
#

ah, so I've been finangling with lifetimes with the trait method for a day and hadn't been able to get it, but trying one last thing did the trick. Thanks for the suggestion @stone egret I'll have the solution up shortly

#

Here are the types for the Waveform:

pub trait MutSlice {
    type Output<'a>: DerefMut<Target=[u8]> where Self: 'a;
    
    fn mut_slice<'a>(&'a mut self) -> Self::Output<'a>;
}

pub struct Waveform<Img: MutSlice> {
    samples: Vec<i16>,
    bin_mips: Vec<Vec<Bin>>,
    zoom_cutoff: f64,
    image: Rc<RefCell<Img>>,
    buffer_width: i32,
    buffer_height: i32,
    buffer_stride: i32,
    theme: Theme,
}

And then for the code to integrate with the waveform:

struct ImageWrapper {
    pub image: ImageSurface,
}

impl waveform::MutSlice for ImageWrapper {
    type Output<'a> = ImageSurfaceData<'a>;

    fn mut_slice<'a>(&'a mut self) -> Self::Output<'a> {
        self.image.data().unwrap()
    }
}
stone egret
#

Looks good!

#

Just for naming, by convention the trait should probably be called AsSliceMut and it's method also as_slice_mut

#

and it's associated type maybe SliceMut