I'm trying to port some code to Rust and have run into a problem. The issue I have is that my function (a Rocket get handler) takes in two parameters, one mandatory and one optional, and it needs to turn this into a query for rusqlite.
This is the function:
#[get("/mkacc_get?<username>&<realname>")]
fn make_account_get(shstate: State<'_, SharedState>,
username: String, realname: Option<String>) -> JsonValue {
let state = shstate.lock().expect("shared state lock");
let mut names = Vec::new();
let mut params = Vec::new();
let mut vals: Vec<&dyn ToSql> = Vec::new();
names.push("username".to_string());
params.push("?".to_string());
vals.push(&username);
if let Some(realname) = realname {
names.push("realname".to_string());
params.push("?".to_string());
vals.push(&realname);
}
let q = format!("INSERT INTO {} ({})", strutil::join(&names, ","),
strutil::join(¶ms, ","));
match state.conn.execute(&q, &vals[..]) {
Ok(_) => {
json!({ "success": true, "id": state.conn.last_insert_rowid() })
}
Err(_) => {
json!({ "success": false, "reason": "db error" })
}
}
}
The problem is obvious: Once I've realized that I have a realname
I want to add it to the vals
vector, but realname
exits the scope very soon after, so due to lifetime issues I can't do that. But it's not clear to me how one would go about solving this. Is there a way to get a reference to the value within the Option without needing to isolate it in a new scope?
Taking a step back and completely ignoring how I'm trying to do it -- how would you go about performing dynamic-number-of-parameter queries using rusqlite?