edgedb-rust
edgedb-rust copied to clipboard
Implement Queryable for all non-contradictory stdlib types
Would something like this be sufficient?
trait Queryable {
...
}
macro_rules! impl_queryable {
($($ty:ty),*) => {
$(
impl Queryable for $ty {
....
}
}
)*
}
}
impl_queryable!(u8, i8, u16, i16, u32, i32, u64, i64);
Usually I'm trying to avoid macros. Also I don't think we can have impl for some of listed types, which we don't want have in the database itself. (e.g. we don't have u8 and i8, and u8 may be stored as u16 or as i16) But I think we can have impl for NonZeroU32 (which is probably macro-incompatible with u32 impl).
Also I think it's about Paths and maybe CStrings and various containers which don't have generalization on macro level I think.
I'd at least use a macro for tuples.
For integers I'd first wait to see if edgedb adds native support for additional integer sizes (with u8 causing complications because it could be an array of bytes, or the Bytes type).
Ah, okay; thank you for explaining. I didn't realize the amount of complexity involved with each of the types when I had suggested the impl_queryable! idea.
Do I understand correctly that this will solve my problem:
#[derive(Queryable, Serialize)]
struct SelectedUser {
id: Uuid,
created_at: DateTime,
phone: String,
}
async fn endpoint(State(AppContext { edb }): State<AppContext>) -> Json<SelectedUser> {
let query = "
select std::assert_single((
select User {
id,
created_at,
phone
} filter (User.phone = <str>$0)
))
";
let found_user: SelectedUser = edb.query_required_single(query, &("+790000000",)).await.unwrap();
return Json(found_user);
}
the trait bound `edgedb_protocol::model::Uuid: Serialize` is not satisfied
the following other types implement trait `Serialize`
required by a bound in `_::_serde::ser::SerializeStruct::serialize_field`
the trait bound `edgedb_protocol::model::Datetime: Serialize` is not satisfied
the following other types implement trait `Serialize`:
So I will able to use id: String and created_at: i64 instead?
Or should I create separate issue?
Hey @MrFoxPro
How are you handling
the trait bound `edgedb_protocol::model::Uuid: Serialize` is not satisfied
Hey @MrFoxPro
How are you handling
the trait bound `edgedb_protocol::model::Uuid: Serialize` is not satisfied
You can use something like this instead of Queryable:
#[derive(Clone)]
pub struct EdgedbSerdeClient(pub edgedb_tokio::Client);
impl EdgedbSerdeClient {
pub async fn query_serde<R, A>(&self, query: impl AsRef<str>, arguments: &A) -> Result<Vec<R>, anyhow::Error>
where
A: QueryArgs,
R: serde::de::DeserializeOwned,
{
let json = self.query_json(query, arguments).await?;
let parsed = serde_json::from_str::<Vec<R>>(&json)?;
Ok(parsed)
}
pub async fn query_single_serde<R, A>(
&self,
query: impl AsRef<str>,
arguments: &A,
) -> Result<Option<R>, anyhow::Error>
where
A: QueryArgs,
R: serde::de::DeserializeOwned,
{
let json = self.query_single_json(query, arguments).await?;
if let Some(json) = json {
let parsed = serde_json::from_str::<Option<R>>(&json)?;
return Ok(parsed);
}
return Ok(None);
}
pub async fn query_required_single_serde<R, A>(
&self,
query: impl AsRef<str>,
arguments: &A,
) -> Result<R, anyhow::Error>
where
A: QueryArgs,
R: serde::de::DeserializeOwned,
{
let json = self.query_required_single_json(query, arguments).await?;
let parsed = serde_json::from_str::<R>(&json)?;
return Ok(parsed);
}
}
impl std::ops::Deref for EdgedbSerdeClient {
type Target = edgedb_tokio::Client;
fn deref(&self) -> &Self::Target {
&self.0
}
}