So I have this code which uses rusqlite. And it works fine.
pub struct Database {
conn: Connection,
}
impl Database {
pub fn get(self: &Self, id: Option<u64>, name: Option<&str>) -> Result<Option<Record>, Error> {
let mut stmt = match name {
Some(_) => { self.conn.prepare_cached(Self::STMT_GET_ID_NAME) },
None => { self.conn.prepare_cached(Self::STMT_GET_ID) }
}?;
let mut rows = match name {
Some(name) => { stmt.query(params![id, name]) },
None => { stmt.query(params![id]) }
}?;
let row = rows.next()?;
if let Some(row) = row {
let record = Record {
id: row.get(0)?,
parent: row.get(1)?,
name: row.get(2)?,
record_type: row.get(3)?,
timestamp: row.get(4)?,
created_at: row.get(5)?,
modified_at: row.get(6)?,
size: row.get(7)?,
hash: row.get(8)?,
inode: row.get(9)?
};
Ok(Some(record))
} else {
Ok(None)
}
}
}
The problem I have is that the match statement is essentially duplicated.
I tried something like this but this won't work.
let (mut stmt, mut rows) = match name {
Some(name) => {
let mut stmt = self.conn.prepare_cached(Self::STMT_GET_ID_NAME)?;
let rows = stmt.query(params![id, name])?;
(stmt, rows)
}
None => {
let mut stmt = self.conn.prepare_cached(Self::STMT_GET_ID)?;
let rows = stmt.query(params![id])?;
(stmt, rows)
}
};
The problem is that the compiler complains about the lifetime of stmt
error[E0597]: `stmt` does not live long enough
error[E0505]: cannot move out of `stmt` because it is borrowed
I really tried a lot of things and try to google furiously. But I'm stuck.
Is there even a way to do this that is not utterly ugly and idiomatic? I feel like this is a really dumb problem, and I'm missing something fundamental here...