edgedb / edgedb-rust

The official Rust binding for EdgeDB
https://edgedb.com
Apache License 2.0
213 stars 26 forks source link

Add support for link properties in derive macro #201

Open XAMPPRocky opened 1 year ago

XAMPPRocky commented 1 year ago

As far I can tell there's no way to use link properties in the derive macro currently, instead you need to map from edged_protocol::Value into the type you want in order to be able to use a type that contains a link. This is very unergonomic as most if not all the types we've been using thus far have some sort of link property that we want to access in Rust.

It would be nice if links were properly supported. I'd be happy to lend some time to help implementing this, but I would need guidance on how the decoding of links should work so I can generate the code in the decode implementation.

tailhook commented 1 year ago

decoding of links

If you mean "decoding of link properties", they are the same as normal properties, except for a flag. We probably have to make a Rust attribute, that basically asserts on that:

#[derive(Queryable)]
struct UserLink {
    // asserts link flag on the `relationship` property descriptor is set
    #[edgedb(link_property)]
    relationship: Relationship,

    // asserts link flag is not set (i.e. a normal property by default)
    username: String,
}
XAMPPRocky commented 1 year ago

If you mean "decoding of link properties", they are the same as normal properties, except for a flag. We probably have to make a Rust attribute

That is what I meant, what you proposed is what I was thinking (though I think I would have it as #[edgedb(link)] as it's just as clear IMO and shorter). The part I'm unsure about is "how do you add that flag with edgedb_protocol::queryable::Decoder".

tailhook commented 1 year ago

(though I think I would have it as #[edgedb(link)] as it's just as clear IMO and shorter).

Some of the fields in the structure are an actual links. We don't mark those and I think it's fine. Link properties are somewhat special as they appear on objects where they are not defined in the schema (i.e. User object can get relationship link property which is defined on on User schema but on the link itself, so in different places User object will get different link properties).

The part I'm unsure about is "how do you add that flag with edgedb_protocol::queryable::Decoder".

I'm not sure I understand the question. But flag is here: https://github.com/edgedb/edgedb-rust/blob/9b125d0cc1c64c9ee69a98800125a6e79d0201dc/edgedb-protocol/src/descriptors.rs#L70 And can be checked like this: https://github.com/edgedb/edgedb-rust/blob/9b125d0cc1c64c9ee69a98800125a6e79d0201dc/edgedb-derive/src/shape.rs#L56

Although, as I'm looking on the code, we don't check the flag anywhere. So you should be able to read link property as a normal property right now without any annotation. Which I consider a bug, but you can abuse it for now.