oddcowboy
oddcowboy

Reputation: 73

How to serialise into an array of slices?

Suppose I have a trait representing a pure function; memory has been provided for the outputs, and both inputs and outputs are expected to be serde/bincode encoded. Is it possible to make this do what I want, or restructure things to enable the same end idiomatically?

trait Pure {
    fn pure(inputs: &[&[u8]], outputs: &[&mut [u8]]);
}

struct Identity {}

impl Pure for Identity {
    fn pure(inputs: &[&[u8]], outputs: &[&mut [u8]]) {
        let x: u32 = bincode::deserialize(inputs[0]).expect("input decode failed");
        bincode::serialize_into(outputs[0], &x).unwrap();
    }
}

makes the compiler complain:

error[E0508]: cannot move out of type `[&mut [u8]]`, a non-copy slice
  --> src/main.rs:10:33
   |
10 |         bincode::serialize_into(outputs[0], &x).unwrap();
   |                                 ^^^^^^^^^^
   |                                 |
   |                                 cannot move out of here
   |                                 move occurs because `outputs[_]` has type `&mut [u8]`, which does not implement the `Copy` trait

Upvotes: 1

Views: 64

Answers (1)

Jmb
Jmb

Reputation: 23443

There are two issues with your code. First, if you want to be able to mutate the inner references, then you must have a mutable outer reference. IOW, your pure function should take a &mut[&mut [u8]] for parameter.

Second, in order to pass the mutable reference to deserialize_into, you need to reborrow it, to make it clear to the compiler that you are not permanently taking it out of output:

trait Pure {
    fn pure(inputs: &[&[u8]], outputs: &mut[&mut [u8]]);
                                     // ^^^ add this
}

struct Identity {}

impl Pure for Identity {
    fn pure(inputs: &[&[u8]], outputs: &mut[&mut [u8]]) {
                                     // ^^^ add this
        let x: u32 = bincode::deserialize(inputs[0]).expect("input decode failed");
        bincode::serialize_into(&mut*outputs[0], &x).unwrap();
                             // ^^^^^ add this
    }
}

Playground

Upvotes: 1

Related Questions