Skip to content

Potential ergonomic improvements for Queryable #460

Description

@dustypomerleau

It's quite exciting to see all of the progress being made on gel-rust. One feature that I'd like to use more often is the Queryable derive macro, but I'm running into certain limitations.

Here is an example of code I'd like to write:

module default {
    scalar type Position extending int32 {
        constraint min_value(0);
        constraint max_value(100);
    }

    type Widget {
         required size: int32 { constraint min_value(0); }
         required position: Position;
    }
}
pub struct Ready;

#[derive(Queryable)]
pub struct Position(i32);

#[derive(Queryable)]
pub struct Widget<State = Ready> {
    size: u32,
    position: Position,
    state: PhantomData<State>,
}

All 3 of the fields in the Rust Widget will error when deriving Queryable:

  1. DecodeScalar is not implemented for u32
  2. No newtypes: only named fields are supported
  3. DecodeScalar is not implemented for PhantomData<State>

My impression is that the main options in that situation are:

  1. Query as <json> and use serde_json::from_str(), so that my struct now looks more like:
#[derive(Deserialize, Serialize)]
pub struct Widget<State = Ready> {
    size: u32,
    position: Position,
    #[serde(skip)]
    state: PhantomData<State>,
  1. Create a dedicated struct for the query and do some conversion:
#[derive(Queryable)]
pub struct QueryWidget {
    size: i32,
    position: i32,
}

impl TryFrom<QueryWidget> for Widget<Ready> {...}

I don't know what the long term view is on the Queryable derive macro, but I would love to be able to annotate some of these fields so that I could use my original Widget with Queryable, without having to pass through JSON. I'm picturing serde-like field attributes that would look something like:

#[derive(Queryable)]
pub struct Widget<State = Ready> {
    #[gel(cast)]
    size: u32,
    #[gel(transparent)]
    position: Position,
    #[gel(skip)]
    state: PhantomData<State>,
}

I realize that things like integer casts could fail if the DB constraints are not correct, but since the query methods on the gel-tokio Client already return Result, I think the user could be expected to handle such cases.

All of this assumes that there isn't a much easier path, such as implementing DecodeScalar for the types in question, and doing the cast/skip under the hood somehow.

Does any of this sound feasible/reasonable? As always, I appreciate your time.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions