Obligatory disclaimer: I'm definitely no Rust/SQL expert, but I'm still learning. I'd appreciate any help in this process.
I am trying to encode a struct containing a field of type Arc<RwLock<json>>
into the jsonb
PostgreSQL type using the sqlx crate. My code takes the general form:
...
use std::sync::Arc;
use parking_lot::RwLock;
use serde_json::value::Value as json;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ArcJson {
pub data: Arc<RwLock<json>>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct MyStruct {
...
pub my_data: ArcJson,
}
...
// this is an associated function (self is sqlx::postgres::PgPool)
pub async fn add_my_struct_instance_to_db(self, my_new_data: MyStruct) -> Result<MyStruct, sqlx::Error> {
match sqlx::query("INSERT INTO postgres_table (..., postgres_jsonb_data) VALUES ($1, $2) RETURNING ..., postgres_jsonb_data")
.bind(my_new_data.my_data)
.map(|row: PgRow| MyStruct{
...
my_data: ArcJson {data: Arc::new(RwLock::new(row.get("data")))},
})
.fetch_one(&self.connection)
.await{
Ok(data) => Ok(data),
Err(e) => Err(e)
}
}
The error I'm getting is that the trait bound 'ArcJson Encode<_, Postgres>' is not satisfied.
I've tried to derive sqlx::Type for ArcJson to no avail. What is the simplest way to basically say "to convert all you have to do is read the locks and clone the internal json"? (I know cloning here isn't the most efficient thing, but I'd like to avoid going down this sort of rabbit hole if I can avoid it for now).
Lifetime annotations scare me, but they're required to manually implement encode. Can anyone advise on how I should proceed? I'm not sure if my brain is just too small or I'm over-complicating things.
PS: I tried to simplify the code as much as possible to best convey the gist of the issue, please let me know if it is unclear or confusing