I would like write a Rust function that, provided a rusqlite::Statement
and a time interval (from, to), returns a rusqlite::MappedRows
that I can then use as an interator to read rows from a database.
The get_mapped_rows
function should return the MappedRows
struct:
fn get_mapped_rows<'stmt>(
stmt: &'stmt Statement,
from: u64,
to: u64
)-> MappedRows<'stmt, FnMut(&Row<'_>) -> Result<FromSql, Error>> {
stmt
.query(params![from, to])
.unwrap()
.mapped(Box::new(|row| {
Ok(Box::new(row.get(0)?) as Box<dyn FromSql>)
}))
}
And get_rows below calls it:
fn get_rows(conn: &mut Connection) {
let mut stmt =
conn.prepare("SELECT dbl_time FROM log WHERE time >= ?1 AND time < ?2")
.unwrap();
let mapped_rows = get_mapped_rows(stmt, 2, 4);
while let Some(row_result) = mapped_rows.next() {
match row_result {
Ok(dbl_time) => { println!("dbl_time: {}", dbl_time); },
_ => panic!("What happened?!"),
}
}
}
When compiling I get the following error:
error[E0782]: trait objects must include the `dyn` keyword
--> src/main.rs:48:23
|
48 | )-> MappedRows<'stmt, FnMut(&Row<'_>) -> Result<FromSql, Error>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: add `dyn` keyword before this trait
|
48 | )-> MappedRows<'stmt, dyn FnMut(&Row<'_>) -> Result<FromSql, Error>> {
| +++
error[E0782]: trait objects must include the `dyn` keyword
--> src/main.rs:48:49
|
48 | )-> MappedRows<'stmt, FnMut(&Row<'_>) -> Result<FromSql, Error>> {
| ^^^^^^^
|
help: add `dyn` keyword before this trait
|
48 | )-> MappedRows<'stmt, FnMut(&Row<'_>) -> Result<dyn FromSql, Error>> {
| +++
I tried adding dyn
according to the hints and a lot of other things including Box
ing the FnMut
and the FromSql
part of the result. But no luck. I am getting the feeling that this is not the right way to solve my problem.
Update: This is what made it work:
fn get_mapped_rows<'stmt>(
stmt: &'stmt mut Statement,
from: u64,
to: u64
)-> MappedRows<'stmt, impl FnMut(&Row<'_>) -> Result<i64, Error>> {
stmt
.query(params![from, to])
.unwrap()
.mapped(|row| {
Ok(row.get(0)?)
})
}
I got it working by updating the get_mapped_rows
function to the following:
fn get_mapped_rows<'stmt>(
stmt: &'stmt mut Statement,
from: u64,
to: u64
)-> MappedRows<'stmt, impl FnMut(&Row<'_>) -> Result<i64, Error>> {
stmt
.query(params![from, to])
.unwrap()
.mapped(|row| {
Ok(row.get(0)?)
})
}
What I learnt here is that you use impl FnMut
to indicate a type known by the compiler (or rather, a signature I guess?). I tried initially to use impl FromSql
instead of i64
in the Result
but the compiler did not like that.