I'm using redb as a storage, and I wrote a Function
pub(crate) fn query<'a, K, V, KEY, D>(table: TableDefinition<K, V>, key: KEY) -> Result<Option<D>>
where
K: redb::RedbKey,
V: redb::RedbValue<SelfType<'a> = &'a [u8]>,
D: serde::de::DeserializeOwned,
KEY: Borrow<&'a str> + std::borrow::Borrow<<K as redb::RedbValue>::SelfType<'a>>,
{
let read: redb::ReadTransaction<'a> = DB.begin_read()?;
let table: redb::ReadOnlyTable<'a, K, V> = read.open_table(table)?;
let r: Option<redb::AccessGuard<'a, V>> = table.get(key)?;
if let Some(d) = r {
let s: D = serde_json::from_slice(d.value())?;
Ok(Some(s))
} else {
Ok(None)
}
}
Compiler didn't happy
error[E0597]: `read` does not live long enough
--> src\db\mod.rs:212:17
|
204 | pub(crate) fn query<'a, K, V, KEY, D>(table: TableDefinition<K, V>, key: KEY) -> Result<Option<D>>
| -- lifetime `'a` defined here
...
211 | let read = DB.begin_read()?;
| ---- binding `read` declared here
212 | let table = read.open_table(table)?;
| ^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
...
215 | let s: D = serde_json::from_slice(d.value())?;
| --------- argument requires that `read` is borrowed for `'a`
...
220 | }
| - `read` dropped here while still borrowed
This is a little bit counterintuitive.
In my opinion, the final result D didn't borrow anything
the only thing I borrowed is KEY, but didn't use it after D returned
I'm not sure I follow. What do you mean by fn<'a>?
If you are asking why I thought that HRTBs would solve your trait bound issues, I saw that you create a reference inside your function that you try to assign to 'a. This is not possible as 'a is a generic parameter. 'a is chosen by the caller. You can't use it for local references (that don't happen to be 'a, i.e. because they reference something that you passed as an argument that binds 'a, i.e. &'a Foo or Foo<'a>). That's when you need HRTBs to express that some trait bound should be valid for any'a (allowing you to chose 'a yourself, instead of the caller).
error: implementation of `Borrow` is not general enough
--> src\man\settings.rs:34:39
|
34 | let r: Result<Option<Settings>> = db::query(TABLE, SETTINGS_KEY);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Borrow` is not general enough
|
= note: `&'2 str` must implement `Borrow<&'1 str>`, for any lifetime `'1`...
= note: ...but it actually implements `Borrow<&'2 str>`, for some specific lifetime `'2`
I guess this is also a lifetime problem since SETTINGS_KEY has 'static lifetime, but query function needs 'a lifetime