Skip to content

Commit

Permalink
Add enum discriminants
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperSonicHub1 committed Jul 21, 2024
1 parent a0a13fb commit 6cde9fe
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/adapter/edges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,16 @@ pub(super) fn resolve_variant_edge<'a, V: AsVertex<Vertex<'a>> + 'a>(
})),
}
}),
"discriminant" => resolve_neighbors_with(contexts, move |vertex| {
let origin = vertex.origin;
let item = vertex.as_variant().expect("vertex was not a Variant");

if let Some(discriminant) = &item.discriminant {
Box::new(std::iter::once(origin.make_discriminant_vertex(discriminant.clone())))
} else {
Box::new(std::iter::empty())
}
}),
_ => unreachable!("resolve_variant_edge {edge_name}"),
}
}
Expand Down
1 change: 1 addition & 0 deletions src/adapter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ impl<'a> Adapter<'a> for RustdocAdapter<'a> {
properties::resolve_associated_constant_property(contexts, property_name)
}
"Constant" => properties::resolve_constant_property(contexts, property_name),
"Discriminant" => properties::resolve_discriminant_property(contexts, property_name),
_ => unreachable!("resolve_property {type_name} {property_name}"),
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/adapter/origin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,11 @@ impl Origin {
kind: abi.into(),
}
}

pub(super) fn make_discriminant_vertex<'a>(&self, discriminant: rustdoc_types::Discriminant) -> Vertex<'a> {
Vertex {
origin: *self,
kind: discriminant.into(),
}
}
}
29 changes: 29 additions & 0 deletions src/adapter/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,3 +560,32 @@ pub(crate) fn resolve_constant_property<'a, V: AsVertex<Vertex<'a>> + 'a>(
_ => unreachable!("Constant property {property_name}"),
}
}

pub(crate) fn resolve_discriminant_property<'a, V: AsVertex<Vertex<'a>> + 'a>(
contexts: ContextIterator<'a, V>,
property_name: &str,
) -> ContextOutcomeIterator<'a, V, FieldValue> {
match property_name {
"expr" => resolve_property_with(
contexts,
|vertex| {
vertex
.as_discriminant()
.expect("vertex was not a Discriminant")
.expr
.into()
},
),
"value" => resolve_property_with(
contexts,
|vertex| {
vertex
.as_discriminant()
.expect("vertex was not a Discriminant")
.value
.into()
},
),
_ => unreachable!("AssociatedConstant property {property_name}"),
}
}
60 changes: 60 additions & 0 deletions src/adapter/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1657,3 +1657,63 @@ fn unions() {

similar_asserts::assert_eq!(expected_results, results);
}

#[test]
fn enum_discriminants() {
let path = "./localdata/test_data/enum_discriminants/rustdoc.json";
let content = std::fs::read_to_string(path)
.with_context(|| format!("Could not load {path} file, did you forget to run ./scripts/regenerate_test_rustdocs.sh ?"))
.expect("failed to load rustdoc");

let crate_ = serde_json::from_str(&content).expect("failed to parse rustdoc");
let indexed_crate = IndexedCrate::new(&crate_);
let adapter = RustdocAdapter::new(&indexed_crate, None);

let query = r#"
{
Crate {
item {
... on Enum {
variant {
discriminant {
expr @output
value @output
}
}
}
}
}
}
"#;
let variables: BTreeMap<&str, &str> = btreemap! {};

let schema =
Schema::parse(include_str!("../rustdoc_schema.graphql")).expect("schema failed to parse");

#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, serde::Deserialize)]
struct Output {
expr: String,
value: String,
}

let mut results: Vec<Output> =
trustfall::execute_query(&schema, adapter.into(), query, variables.clone())
.expect("failed to run query")
.map(|row| row.try_into_struct().expect("shape mismatch"))
.collect();
results.sort_unstable();

similar_asserts::assert_eq!(
vec![
Output {
expr: "1".into(),
value: "1".into(),
},
Output {
expr: "{ _ }".into(),
value: "2".into(),
},
],
results
);
}
17 changes: 16 additions & 1 deletion src/adapter/vertex.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::rc::Rc;

use rustdoc_types::{
Abi, Constant, Crate, Enum, Function, Impl, Item, Module, Path, Span, Static, Struct, Trait,
Abi, Constant, Crate, Discriminant, Enum, Function, Impl, Item, Module, Path, Span, Static, Struct, Trait,
Type, Union, Variant, VariantKind,
};
use trustfall::provider::Typename;
Expand Down Expand Up @@ -36,6 +36,7 @@ pub enum VertexKind<'a> {
ImplementedTrait(&'a Path, &'a Item),
FunctionParameter(&'a str),
FunctionAbi(&'a Abi),
Discriminant(Discriminant),
}

impl<'a> Typename for Vertex<'a> {
Expand Down Expand Up @@ -77,6 +78,7 @@ impl<'a> Typename for Vertex<'a> {
},
VertexKind::FunctionParameter(..) => "FunctionParameter",
VertexKind::FunctionAbi(..) => "FunctionAbi",
VertexKind::Discriminant(..) => "Discriminant",
}
}
}
Expand Down Expand Up @@ -254,6 +256,13 @@ impl<'a> Vertex<'a> {
_ => None,
}
}

pub(super) fn as_discriminant(&self) -> Option<rustdoc_types::Discriminant> {
match &self.kind {
VertexKind::Discriminant(discriminant) => Some(discriminant.clone()),
_ => None,
}
}
}

impl<'a> From<&'a Item> for VertexKind<'a> {
Expand All @@ -279,3 +288,9 @@ impl<'a> From<&'a Abi> for VertexKind<'a> {
Self::FunctionAbi(a)
}
}

impl<'a> From<Discriminant> for VertexKind<'a> {
fn from(d: Discriminant) -> Self {
Self::Discriminant(d)
}
}
12 changes: 12 additions & 0 deletions src/rustdoc_schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,15 @@ interface Variant implements Item {

# own edges
field: [StructField!]
discriminant: Discriminant
}

"""
https://docs.rs/rustdoc-types/latest/rustdoc_types/struct.Discriminant.html
"""
type Discriminant {
expr: String!
value: String!
}

"""
Expand Down Expand Up @@ -483,6 +492,7 @@ type PlainVariant implements Item & Variant {

# edges from Variant
field: [StructField!]
discriminant: Discriminant
}

"""
Expand Down Expand Up @@ -537,6 +547,7 @@ type TupleVariant implements Item & Variant {

# edges from Variant
field: [StructField!]
discriminant: Discriminant
}

"""
Expand Down Expand Up @@ -591,6 +602,7 @@ type StructVariant implements Item & Variant {

# edges from Variant
field: [StructField!]
discriminant: Discriminant
}

"""
Expand Down
9 changes: 9 additions & 0 deletions test_crates/enum_discriminants/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
publish = false
name = "enum_discriminants"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
5 changes: 5 additions & 0 deletions test_crates/enum_discriminants/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[repr(C)]
pub enum A {
One = 1,
Two = 1 + 1,
}

0 comments on commit 6cde9fe

Please sign in to comment.