Hello! I am new to Rust and struggling with the compiler. I need to tell it that my function is generic over any tuple as long as each element satisfies the FromSql trait but don't know how to do that. I am trying to make a function to factor out these two similar pieces of code:
// somewhere above: extern crate oracle;
conn.query_as::<(String,)>("select A from ...", &[]);
...
conn.query_as::<(String,String,String)>("select X,Y,Z from ...", &[])
The trait was added to fetch column values as a tuple. The oracle crate provides implementations for a type implementing FromSql and tuples of types implementing FromSql. The number of elements in a tuple should be 1 through 50.
There is already impl FromSql for String. So I have everything necessary, and I just need to persuade the compiler
Rust doesn't have variadic generics, so you can't express a concept of "any tuple". In Rust tuples aren't like arrays or lists, but more like structs without field names, so they don't have a length.
The current solution is to use a macro that repeats definition for specific tuples with certain number of elements, like 1 to 15.
Another (more drastic) option is to go full frunk, and implement FromSql for HList (or similar), then you can basically get variadic generics with a different syntax.
Thank you! How would I do it here? Do I need to repeat the whole sql_to_s3, once using conn.query_as::<String> and once conn.query_as::<(String, String, String)> internally?
Solved: I can use T: RowValue instead since the oracle crate implements it for various types of tuples and it is the type the query_as method actually wants:
fn sql_to_s3<T: RowValue + Serialize>( ...
Though without that, using a macro as suggested would be the best solution.