I want to implement the trait Backend
below on a custom key-value store client
pub trait Backend {
/// pushes the data to the backend
///
/// `push` should handle how the data is stored, ie: double linkedlist...etc
fn push(&mut self, key: &[u8], data: &[u8]) -> Result<()>;
/// gets the data associated with key provided from the backend
///
/// `fetch` should handle how the data is fetched
fn fetch(&self, key: &[u8]) -> Result<Option<&[u8]>>;
}
so firlsty I started testing by implementing Backend
for HashMap
collection and all was fine
impl Backend for HashMap<Vec<u8>, Vec<u8>> {
fn push(&mut self, key: &[u8], data: &[u8]) -> Result<()> {
self.insert(key.to_vec(), data.to_vec());
Ok(())
}
fn fetch(&self, key: &[u8]) -> Result<Option<&[u8]>> {
let data = self.get(key);
match data {
Some(data) => Ok(Some(&data[..])),
None => Ok(None),
}
}
}
But when I actually tried it on the client
impl Backend for Zstor {
fn push(&mut self, key: &[u8], data: &[u8]) -> Result<()> {
let mut req = model::WriteRequest::new();
req.set_key(key.to_vec());
req.set_data(data.to_vec());
self.client
.write(&req)
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
Ok(())
}
fn fetch<'a>(&self, key: &[u8]) -> Result<Option<&[u8]>> {
let mut req = model::ReadRequest::new();
req.set_key(key.to_vec());
let resp = self.client
.read(&req)
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
// resp.data is Vec<u8>
Ok(Some(&resp.data))
}
}
it gave the below error
Compiling backends v0.1.0 (file:///Users/Khaled/development/github.com/zero-os/tlog/backends)
error[E0597]: `resp.data` does not live long enough
--> src/zstor/mod.rs:44:18
|
44 | Ok(Some(&resp.data))
| ^^^^^^^^^ borrowed value does not live long enough
45 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the method body at 37:5...
--> src/zstor/mod.rs:37:5
|
37 | / fn fetch(&self, key: &[u8]) -> Result<Option<&[u8]>> {
38 | | let mut req = model::ReadRequest::new();
39 | | req.set_key(key.to_vec());
40 | | let resp = self.client
... |
44 | | Ok(Some(&resp.data))
45 | | }
| |_____^
error: aborting due to previous error
I understand that the problem is that resp
doesn't live long enough so a reference to it does not make sense. However as far as I can see it's the same case as the HashMap
implementation.
I need help to understand this situation and how to fix it aside from changing the fetch
method return to a Vec
and I even tried to clone data or resp and return the ref to it but it didn't work as expected.