Building a dynamic query in SQLx with `optional_field::Field`
ā Rust š 2026-06-10 š¤ surdeus šļø 3Iām struggling to create a heterogeneous Vec containing instances of optional_field::Field for use with SQLx:
trait FieldValue<'a>: sqlx::Encode<'a, Sqlite> + sqlx::Type<Sqlite> {}
fn build_update<'a, T: FromRow<'a, SqliteRow>>(
table: &'static str,
id: RawIdType,
fields: Vec<(&'static str, Field<Box<dyn FieldValue<'a>>>)>,
) -> QueryAs<'a, Sqlite, T, SqliteArguments> {
let mut query: QueryBuilder<Sqlite> = QueryBuilder::new(format!("UPDATE {table} SET "));
{
let mut separated = query.separated(", ");
for (name, field) in fields {
add_field(name, field, &mut separated);
}
}
constrain_update(id, &mut query);
query.build_query_as()
}
pub fn add_field<'a, T>(
name: &str,
field: Field<Box<T>>,
query: &mut sqlx::query_builder::Separated<Sqlite, &str>,
) where
T: sqlx::Type<Sqlite> + sqlx::Encode<'a, Sqlite>,
{
match field {
Field::Present(Some(val)) => {
query.push(name);
query.push_unseparated(" = ");
query.push_bind_unseparated(*val);
}
Field::Present(None) => {
query.push(name);
query.push_unseparated(" = ");
query.push_unseparated("NULL");
}
_ => {}
}
}
pub fn constrain_update(id: RawIdType, query: &mut QueryBuilder<Sqlite>) {
// omitted
}
I created that FieldValue trait based on a compiler error about auto traits but now I get:
error[E0038]: the trait `FieldValue` is not dyn compatible
--> crates\server\src\db.rs:73:42
|
73 | fields: Vec<(&'static str, Field<Box<dyn FieldValue<'a>>>)>,
| ^^^^^^^^^^^^^^^^^^ `FieldValue` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> C:\Users\A\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\sqlx-core-0.9.0\src\types\mod.rs:219:8
Is there a way I can phrase this to satisfy the compiler?
1 post - 1 participant
š·ļø Rust_feed