obi1kenobi / trustfall-rustdoc-adapter

Trustfall adapter for querying rustdoc
Apache License 2.0
12 stars 18 forks source link

Get generic parameters for a struct field #566

Open oknozor opened 5 days ago

oknozor commented 5 days ago

I am not sure if I am missing something or if this is not possible with the current graphql schema.

Example: Let's say I have the following struct in my crate:

struct MySettings {
  a: HashMap<String, MyConfig>
}

struct MyConfig {
  value: u16
}

I now want to query rustdoc like so:

query {
  Crate {
    item {
      ... on Struct {
        name @filter(op: "=", value: ["$struct_name"])

        field {
          field_name: name @output
          raw_type {
            type_name: name @output
          }
        }
      }
    }
  }
}

I would get something like that in the query output:

{
    "field_name": "a",
    "type_name":  "std::collections::HashMap",
}

I want to retrieve the HashMap generic parameters to run another query that would retrieve data for MyConfig.

Context:

I am trying to automate generation of a config reference documentation. initially I tried to use schemars which seemed to fit the usecase perfectly, until I stumble on the same issue with Map generics parameter not being parsed (see: https://github.com/GREsau/schemars/issues/124).

obi1kenobi commented 4 days ago

Hi @oknozor, unfortunately this isn't possible yet, but I have a possible workaround. We're making steady progress toward expressing this in the schema, but I don't have a concrete timeline to offer.

I think using a more recent version of the adapter (after #528) might make it so that the generics are printed as part of type_name in your query, but I'm not sure. (The RawType schema type is documented as "permanently unstable" and intended for experimentation, so I'm not 100% sure about its status right now.) But that's not as part of the schema, so it isn't a full solution by any stretch.

If the above isn't good enough, I'd recommend grabbing the id property of the StructField type (inside the field edge) and looking up the field type inside the rustdoc index directly. This is a workaround that will get you the full type info, though you'll still have to deal with the Rust type system's complexity mentioned here šŸ‘‡

As for the full solution: modeling Rust types properly in our schema is quite hard: we have to represent everything from &impl Trait + 'a to for<'a> Fn(&'a i64) -> (&'a i64, String) to <Self as Iterator>::Item and everything in between. Recently, we extended the schema to expose generics information on top-level items (structs, enums, unions, traits, impls, functions) and on trait bounds: #514, #554, #560. We obviously have a bunch of work to do, though we are making progress.

If that work is useful to you, I'd appreciate it if you'd consider sponsoring my work! I'd love to pay my rent with this work so I can spend more time doing it ā¤

obi1kenobi commented 4 days ago

Also, not sure if I've already invited you to join the Trustfall / cargo-semver-checks community Discord ā€” here's an invite link just in case: https://discord.gg/HGg95qSf

oknozor commented 3 days ago

Thanks, seems I will be able to parse generics from the raw type field using the latest version. Feels a bit hacky but that will do for now.

obi1kenobi commented 3 days ago

Neat, good luck!