graphql_tools/introspection/
mod.rs1#![allow(non_camel_case_types)]
2use std::io;
3
4use serde::{Deserialize, Serialize};
5use serde_json::{Result, Value};
6
7#[derive(Serialize, Deserialize, Debug)]
8pub struct IntrospectionQuery {
9 pub __schema: IntrospectionSchema,
10}
11
12#[derive(Serialize, Deserialize, Debug)]
13pub struct IntrospectionScalarType {
14 pub name: String,
15 pub description: Option<String>,
16 #[serde(rename = "specifiedByURL")]
17 pub specified_by_url: Option<String>,
18}
19
20#[derive(Serialize, Deserialize, Debug)]
21pub struct IntrospectionInputValue {
22 pub name: String,
23 pub description: Option<String>,
24 #[serde(rename = "defaultValue")]
25 pub default_value: Option<Value>,
26 #[serde(rename = "isDeprecated")]
27 pub is_deprecated: Option<bool>,
28 #[serde(rename = "deprecationReason")]
29 pub deprecation_reason: Option<String>,
30 #[serde(rename = "type")]
31 pub type_ref: Option<IntrospectionInputTypeRef>,
32}
33
34#[derive(Serialize, Deserialize, Debug)]
35#[serde(tag = "kind")]
36pub struct IntrospectionField {
37 pub name: String,
38 pub description: Option<String>,
39 pub args: Vec<IntrospectionInputValue>,
40 #[serde(rename = "isDeprecated")]
41 pub is_deprecated: Option<bool>,
42 #[serde(rename = "deprecationReason")]
43 pub deprecation_reason: Option<String>,
44 #[serde(rename = "type")]
45 pub type_ref: IntrospectionOutputTypeRef,
46}
47
48#[derive(Serialize, Deserialize, Debug)]
49pub struct IntrospectionObjectType {
50 pub name: String,
51 pub description: Option<String>,
52 pub fields: Vec<IntrospectionField>,
53 pub interfaces: Vec<IntrospectionNamedTypeRef>,
54}
55
56#[derive(Serialize, Deserialize, Debug)]
57pub struct IntrospectionInterfaceType {
58 pub name: String,
59 pub description: Option<String>,
60 pub fields: Vec<IntrospectionField>,
61 pub interfaces: Option<Vec<IntrospectionNamedTypeRef>>,
62 #[serde(rename = "possibleTypes")]
63 pub possible_types: Vec<IntrospectionNamedTypeRef>,
64}
65
66#[derive(Serialize, Deserialize, Debug)]
67pub struct IntrospectionUnionType {
68 pub name: String,
69 pub description: Option<String>,
70 #[serde(rename = "possibleTypes")]
71 pub possible_types: Vec<IntrospectionNamedTypeRef>,
72}
73
74#[derive(Serialize, Deserialize, Debug)]
75pub struct IntrospectionEnumValue {
76 pub name: String,
77 pub description: Option<String>,
78 #[serde(rename = "isDeprecated")]
79 pub is_deprecated: Option<bool>,
80 #[serde(rename = "deprecationReason")]
81 pub deprecation_reason: Option<String>,
82}
83
84#[derive(Serialize, Deserialize, Debug)]
85pub struct IntrospectionEnumType {
86 pub name: String,
87 pub description: Option<String>,
88 #[serde(rename = "enumValues")]
89 pub enum_values: Vec<IntrospectionEnumValue>,
90}
91
92#[derive(Serialize, Deserialize, Debug)]
93pub struct IntrospectionInputObjectType {
94 pub name: String,
95 pub description: Option<String>,
96 #[serde(rename = "inputFields")]
97 pub input_fields: Vec<IntrospectionInputValue>,
98}
99
100#[derive(Serialize, Deserialize, Debug)]
101#[serde(tag = "kind")]
102pub enum IntrospectionType {
103 SCALAR(IntrospectionScalarType),
104 OBJECT(IntrospectionObjectType),
105 INTERFACE(IntrospectionInterfaceType),
106 UNION(IntrospectionUnionType),
107 ENUM(IntrospectionEnumType),
108 INPUT_OBJECT(IntrospectionInputObjectType),
109}
110
111impl IntrospectionType {
112 pub fn name(&self) -> &String {
113 match &self {
114 IntrospectionType::ENUM(e) => &e.name,
115 IntrospectionType::OBJECT(o) => &o.name,
116 IntrospectionType::INPUT_OBJECT(io) => &io.name,
117 IntrospectionType::INTERFACE(i) => &i.name,
118 IntrospectionType::SCALAR(s) => &s.name,
119 IntrospectionType::UNION(u) => &u.name,
120 }
121 }
122}
123
124#[derive(Serialize, Deserialize, Debug)]
125#[serde(tag = "kind")]
126pub enum IntrospectionInputType {
127 SCALAR(IntrospectionScalarType),
128 ENUM(IntrospectionEnumType),
129 INPUT_OBJECT(IntrospectionInputObjectType),
130}
131
132#[derive(Serialize, Deserialize, Debug)]
133#[serde(tag = "kind")]
134pub enum IntrospectionOutputType {
135 SCALAR(IntrospectionScalarType),
136 OBJECT(IntrospectionObjectType),
137 INTERFACE(IntrospectionInterfaceType),
138 UNION(IntrospectionUnionType),
139 ENUM(IntrospectionEnumType),
140}
141
142#[derive(Serialize, Deserialize, Debug)]
143pub struct IntrospectionNamedTypeRef {
144 pub name: String,
145}
146
147#[derive(Serialize, Deserialize, Debug)]
148#[serde(tag = "kind")]
149pub enum IntrospectionOutputTypeRef {
150 SCALAR(IntrospectionNamedTypeRef),
151 LIST {
152 #[serde(rename = "ofType")]
153 of_type: Option<Box<IntrospectionOutputTypeRef>>,
154 },
155 NON_NULL {
156 #[serde(rename = "ofType")]
157 of_type: Option<Box<IntrospectionOutputTypeRef>>,
158 },
159 ENUM(IntrospectionNamedTypeRef),
160 INPUT_OBJECT(IntrospectionNamedTypeRef),
161 UNION(IntrospectionNamedTypeRef),
162 OBJECT(IntrospectionNamedTypeRef),
163 INTERFACE(IntrospectionNamedTypeRef),
164}
165
166#[derive(Serialize, Deserialize, Debug)]
167#[serde(tag = "kind")]
168pub enum IntrospectionInputTypeRef {
169 LIST {
170 #[serde(rename = "ofType")]
171 of_type: Option<Box<IntrospectionInputTypeRef>>,
172 },
173 NON_NULL {
174 #[serde(rename = "ofType")]
175 of_type: Option<Box<IntrospectionInputTypeRef>>,
176 },
177 SCALAR(IntrospectionNamedTypeRef),
178 ENUM(IntrospectionNamedTypeRef),
179 INPUT_OBJECT(IntrospectionNamedTypeRef),
180}
181
182#[derive(Serialize, Deserialize, Debug)]
183pub struct IntrospectionSchema {
184 pub description: Option<String>,
185 #[serde(rename = "queryType")]
186 pub query_type: IntrospectionNamedTypeRef,
187 #[serde(rename = "mutationType")]
188 pub mutation_type: Option<IntrospectionNamedTypeRef>,
189 #[serde(rename = "subscriptionType")]
190 pub subscription_type: Option<IntrospectionNamedTypeRef>,
191 pub types: Vec<IntrospectionType>,
192 pub directives: Vec<IntrospectionDirective>,
193}
194
195#[derive(Serialize, Deserialize, Debug)]
196pub enum DirectiveLocation {
197 QUERY,
198 MUTATION,
199 SUBSCRIPTION,
200 FIELD,
201 FRAGMENT_DEFINITION,
202 FRAGMENT_SPREAD,
203 INLINE_FRAGMENT,
204 VARIABLE_DEFINITION,
205 SCHEMA,
207 SCALAR,
208 OBJECT,
209 FIELD_DEFINITION,
210 ARGUMENT_DEFINITION,
211 INTERFACE,
212 UNION,
213 ENUM,
214 ENUM_VALUE,
215 INPUT_OBJECT,
216 INPUT_FIELD_DEFINITION,
217}
218
219#[derive(Serialize, Deserialize, Debug)]
220pub struct IntrospectionDirective {
221 pub name: String,
222 pub description: Option<String>,
223 #[serde(rename = "isRepeatable")]
224 pub is_repeatable: Option<bool>,
225 pub locations: Vec<DirectiveLocation>,
226 pub args: Vec<IntrospectionInputValue>,
227}
228
229pub fn parse_introspection_from_string(input: &str) -> Result<IntrospectionQuery> {
230 serde_json::from_str(input)
231}
232
233pub fn parse_introspection<R>(input: R) -> Result<IntrospectionQuery>
234where
235 R: io::Read,
236{
237 serde_json::from_reader::<R, IntrospectionQuery>(input)
238}
239
240#[test]
241fn test_product_introspection() {
242 use std::fs::File;
243 let json_file = File::open("./src/introspection/test_files/product_introspection.json")
244 .expect("failed to open json file");
245 parse_introspection(json_file).expect("failed to parse introspection json");
246}
247
248#[test]
249fn test_github_introspection() {
250 use std::fs::File;
251 let json_file = File::open("./src/introspection/test_files/github_introspection.json")
252 .expect("failed to open json file");
253 parse_introspection(json_file).expect("failed to parse introspection json");
254}
255
256#[test]
257fn test_shopify_introspection() {
258 use std::fs::File;
259 let json_file = File::open("./src/introspection/test_files/shopify_introspection.json")
260 .expect("failed to open json file");
261 parse_introspection(json_file).expect("failed to parse introspection json");
262}