graphql_tools/introspection/
mod.rs

1#![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    /** Type System Definitions */
206    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}