Reputation: 73
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
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
}
}
Upvotes: 1