Rkyv : mutate u64 field after archiving?

Hi,
Not sure how to handle the following error:

cannot borrow data in dereference of ArchivedVec<ArchivedStrt> as mutable
trait DerefMut is required to modify through a dereference, but it is not implemented for `ArchivedVec

for the following code:

#[derive(Archive, Deserialize, Serialize, Default)]

enum Hm {
    #[default]
    ONE,
    TWO,

    THREE,
}

#[derive(Archive, Deserialize, Serialize, Default)]

struct Strt {
    what: String,
    how: u64,
    hm: Hm,
}

#[derive(Archive, Deserialize, Serialize, Default)]

struct MyStruct {
    vec: Vec<Strt>,
    p: u32,
}

fn main() {
    const ARBITRARY_VALUE: u64 = 3;

    let mut buffer: MyStruct = Default::default();

    buffer.p = 55;

    for i in 0..ARBITRARY_VALUE {
        let mut s: Strt = Default::default();

        s.how = 65 + i;

        s.what = format!("Test {}", i);

        buffer.vec.push(s);
    }

    let mut u: AlignedVec = rkyv::to_bytes::<MyStruct, 1024>(&buffer).unwrap();

    let z = unsafe { rkyv::archived_root_mut::<MyStruct>(std::pin::Pin { pointer: &mut u }) };

    for i in z.vec.iter_mut() { <- issue is here
        // try to update this value
        i.how += 5;
    }
}

What I want is to modify the how value for testing purposes.
I tried to put different types to see how it behaves for later mutations.
Should I modify the Strt::string, it would only be for less than or equal size data.

Is there an automatic DerefMut implementation I could rely on ? Is there a derivable I forgot?

Sorry guys, I couldn't put my example in a playground, because of the absence of rkyv in the playground libs (apparently).

Thanks,

It looks like you want pin_mut_slice.

1 Like

I am really sorry,

All my attempts failed to retrieve the pin_mut_slice

I don't get how to write my code so it appears
Anything special to import ?

The issue being that ArchivecVec should let me access the pin_mut_slice, but doesn't.

Reusing the code in the first post, I should have it to available when writing z.vec.pin_mut_slice() but I don't.

What is the correct way to retrieve it ?

Using rkyv::vec::ArchivedVec::pin_mut_slice(Pin::new(&mut z.vec )); looked promising but now I have

`PhantomPinned` cannot be unpinned
consider using the `pin!` macro
consider using `Box::pin` if you need to access the pinned value outside of the current scope

I don't know how to work that out. That's beyond me.
If someone could show a working example I would be very grateful.

For those interested, this is the working code:

impl ArchivedMyStruct {
    pub fn vec_pin(self: Pin<&mut Self>) -> Pin<&mut ArchivedVec<ArchivedStrt>> {
        unsafe { self.map_unchecked_mut(|s| &mut s.vec) }
    }
}
//... other code above...
let o = unsafe { 
    z.as_mut().vec_pin().pin_mut_slice().get_unchecked_mut()  <- this get_unchecked_mut did the trick
};

for i in o.iter_mut() {
    i.how += 100;
}

for i in z.vec.iter() {
    println!("{}", i.how);
}

I had a hard time finding this one but now, looking at it, it looks so simple...

Solved!

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.