Convert Vec<String> to std::rc::RC<Vec<String>>

262 Views Asked by At

I have a function that receives a list of ids and then selects them from a database. I'm passing in a Vec and I found this issue https://github.com/rusqlite/rusqlite/issues/430 which linked to here https://github.com/rusqlite/rusqlite/blob/master/src/vtab/array.rs#L18 and it says // Note: A Rc<Vec<Value>> must be used as the parameter.

I cannot figure out how to convert this Vec to Rc<Vec> is a way that does not produce a compile error. I tried the following:

let values = std::rc::Rc::new(ids.into_iter().copied().map(String::from).collect::<Vec<String>>());
let values = std::rc::Rc::from(ids.into_iter().map(|item| item.to_string()).collect::<Vec<String>>());
let values = std::rc::Rc::from(&ids);

All 3 give the same error with some variation of this part Vec<Rc<Vecstd::string::String>>

the trait bound `Vec<Rc<Vec<std::string::String>>>: ToSql` is not satisfied the following implementations were found: <Vec<u8> as ToSql> required for the cast to the object type `dyn ToSql`

How can I convert this so it comes out as Rc<Vec> and not Vec<Rc<Vec>>

My code is here

fn table_data_to_table(ids: &Vec<String>) -> Vec<data::Item> {
    let db_connection = rusqlite::Connection::open("data.sqlite")
        .expect("Cannot connect to database.");
    let values = std::rc::Rc::new(ids.into_iter().copied().map(String::from).collect::<Vec<String>>());
    let mut statement = db_connection
        .prepare("select * from item where id in rarray(?);")
        .expect("Failed to prepare query.");
    let mut results = statement
        .query_map(rusqlite::params![vec![values]], |row| {
            Ok(database::ItemData {
                id: row.get(0)?,
                name: row.get(1)?,
                time_tp_prepare: row.get(2)?
            })
        });
    match results {
        Ok(rows) => {
            let collection: rusqlite::Result<Vec<database::ItemData>> = rows.collect();
            match collection {
                Ok(items) => {
                    items.iter().map(|item_data| data::Item {
                        id: item_data.id,
                        name: item_data.name,
                        time_to_prepare: item_data.time_tp_prepare
                    }).collect()
                },
                Err(_) => Vec::new(),
            }
        },
        Err(_) => Vec::new()
    }
}
1

There are 1 best solutions below

2
On

Looking at the example you linked your error is in not passing the Rc directly:

.query_map(rusqlite::params![vec![values]], |row| {

vs

.query_map([values], |row| {