Dear Rustaceans,
I'm having trouble to create and return owned object and its borrowed form.
Here's my code snippet.
use core::mem;
/// Existing library to use
#[derive(Debug)]
struct NativeBuf {
buf: [u8],
}
impl NativeBuf {
fn new(buf: &mut [u8]) -> &Self {
unsafe {
mem::transmute::<&[u8], &Self>(buf)
}
}
// More APIs that uses bindgen for calling C libraries.
}
/// Start of my wrapper
#[derive(Debug)]
struct NativeBufHolder<'a> {
native_buf: &'a NativeBuf,
buf: Vec<u8>,
}
impl<'a> NativeBufHolder<'a> {
fn new() -> Self {
let mut buf = Vec::<u8>::with_capacity(50);
buf.resize(50, 0);
let native_buf = NativeBuf::new(buf.as_mut_slice());
Self {
native_buf: native_buf,
buf: buf,
}
}
}
fn main() {
let mut buf = Vec::<u8>::with_capacity(50);
buf.resize(50, 0);
println!("{:?}", NativeBuf::new(buf.as_mut_slice()));
let holder = NativeBufHolder::new();
println!("{:?}", holder);
}
I see following compilation error complaining that I can't return data owned by the current function.
Compiling playground v0.0.1 (/playground)
error[E0515]: cannot return value referencing local variable `buf`
--> src/main.rs:32:9
|
30 | let native_buf = NativeBuf::new(buf.as_mut_slice());
| ------------------ `buf` is borrowed here
31 |
32 | / Self {
33 | | native_buf: native_buf,
34 | | buf: buf,
35 | | }
| |_________^ returns a value referencing data owned by the current function
error[E0505]: cannot move out of `buf` because it is borrowed
--> src/main.rs:34:18
|
26 | impl<'a> NativeBufHolder<'a> {
| -- lifetime `'a` defined here
...
30 | let native_buf = NativeBuf::new(buf.as_mut_slice());
| ------------------ borrow of `buf` occurs here
31 |
32 | / Self {
33 | | native_buf: native_buf,
34 | | buf: buf,
| | ^^^ move out of `buf` occurs here
35 | | }
| |_________- returning this value requires that `buf` is borrowed for `'a`
Some errors have detailed explanations: E0505, E0515.
For more information about an error, try `rustc --explain E0505`.
error: could not compile `playground` due to 2 previous errors
Since I return both owned object and its borrowed item altogether by moving,
I think that there could be a way such as creating internal buf
with lifetime of NativeBufHolder
.
Can someone recommend me a working solution?
I've also took a look at Box<[u8]>
or Box<u8>
but didn't went well. Here's another code snippet.
/// Start of my wrapper
#[derive(Debug)]
struct NativeBufHolder<'a> {
native_buf: &'a NativeBuf,
buf: Box<u8>, // [u8] cause 'trait bounds were not satisfied` error.
}
impl<'a> NativeBufHolder<'a> {
fn new() -> Self {
let mut buf = Box::<u8>::new(50);
let mut raw_buf = Box::into_raw(buf);
let native_buf = NativeBuf::new(raw_buf);
Self {
native_buf: native_buf,
buf: Box::<u8>::from_raw(raw_buf),
}
}
}
This cause expected
&mut [u8], found
*mut u8`