Skip to content

Commit bf15cdf

Browse files
committed
graphql_client_codegen: update to graphql_parser 0.3
Requires 0.3.1 so that `Document<'a, String>::into_static()` exists. Future work can try and reduce the amount of `'static` used throughout the API, but this at least gets 0.3 into a working state.
1 parent 74e2860 commit bf15cdf

File tree

9 files changed

+195
-107
lines changed

9 files changed

+195
-107
lines changed

graphql_client_codegen/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ edition = "2018"
99

1010
[dependencies]
1111
graphql-introspection-query = { version = "0.2.0", path = "../graphql-introspection-query" }
12-
graphql-parser = "0.3"
12+
graphql-parser = "0.3.1"
1313
heck = "0.3"
1414
lazy_static = "1.3"
1515
proc-macro2 = { version = "^1.0", features = [] }

graphql_client_codegen/src/codegen.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,12 +236,16 @@ fn generate_fragment_definitions<'a>(
236236
}
237237

238238
/// For default value constructors.
239-
fn graphql_parser_value_to_literal(
240-
value: &graphql_parser::query::Value,
239+
fn graphql_parser_value_to_literal<'doc, T>(
240+
value: &graphql_parser::query::Value<'doc, T>,
241241
ty: TypeId,
242242
is_optional: bool,
243243
query: &BoundQuery<'_>,
244-
) -> TokenStream {
244+
) -> TokenStream
245+
where
246+
T: graphql_parser::query::Text<'doc>,
247+
T::Value: quote::ToTokens,
248+
{
245249
use graphql_parser::query::Value;
246250

247251
let inner = match value {
@@ -289,11 +293,15 @@ fn graphql_parser_value_to_literal(
289293
}
290294

291295
/// For default value constructors.
292-
fn render_object_literal(
293-
object_map: &BTreeMap<String, graphql_parser::query::Value>,
296+
fn render_object_literal<'doc, T>(
297+
object_map: &BTreeMap<T::Value, graphql_parser::query::Value<'doc, T>>,
294298
input_id: InputId,
295299
query: &BoundQuery<'_>,
296-
) -> TokenStream {
300+
) -> TokenStream
301+
where
302+
T: graphql_parser::query::Text<'doc>,
303+
T::Value: quote::ToTokens,
304+
{
297305
let input = query.schema.get_input(input_id);
298306
let constructor = Ident::new(&input.name, Span::call_site());
299307
let fields: Vec<TokenStream> = input

graphql_client_codegen/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ type CacheMap<T> = std::sync::Mutex<HashMap<std::path::PathBuf, T>>;
4747

4848
lazy_static! {
4949
static ref SCHEMA_CACHE: CacheMap<schema::Schema> = CacheMap::default();
50-
static ref QUERY_CACHE: CacheMap<(String, graphql_parser::query::Document)> =
50+
static ref QUERY_CACHE: CacheMap<(String, graphql_parser::query::Document<'static, String>)> =
5151
CacheMap::default();
5252
}
5353

@@ -74,7 +74,7 @@ pub fn generate_module_token_stream(
7474
schema_string = read_file(v.key())?;
7575
let schema = match schema_extension {
7676
"graphql" | "gql" => {
77-
let s = graphql_parser::schema::parse_schema(&schema_string).map_err(|parser_error| GeneralError(format!("Parser error: {}", parser_error)))?;
77+
let s = graphql_parser::schema::parse_schema::<&str>(&schema_string).map_err(|parser_error| GeneralError(format!("Parser error: {}", parser_error)))?;
7878
schema::Schema::from(s)
7979
}
8080
"json" => {
@@ -97,7 +97,8 @@ pub fn generate_module_token_stream(
9797
hash_map::Entry::Vacant(v) => {
9898
let query_string = read_file(v.key())?;
9999
let query = graphql_parser::parse_query(&query_string)
100-
.map_err(|err| GeneralError(format!("Query parser error: {}", err)))?;
100+
.map_err(|err| GeneralError(format!("Query parser error: {}", err)))?
101+
.into_static();
101102
v.insert((query_string, query)).clone()
102103
}
103104
}

graphql_client_codegen/src/query.rs

Lines changed: 69 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub(crate) struct VariableId(u32);
6161

6262
pub(crate) fn resolve(
6363
schema: &Schema,
64-
query: &graphql_parser::query::Document,
64+
query: &graphql_parser::query::Document<'static, String>,
6565
) -> Result<Query, QueryValidationError> {
6666
let mut resolved_query: Query = Default::default();
6767

@@ -98,22 +98,25 @@ pub(crate) fn resolve(
9898
Ok(resolved_query)
9999
}
100100

101-
fn create_roots(
101+
fn create_roots<'doc, T>(
102102
resolved_query: &mut Query,
103-
query: &graphql_parser::query::Document,
103+
query: &graphql_parser::query::Document<'doc, T>,
104104
schema: &Schema,
105-
) -> Result<(), QueryValidationError> {
105+
) -> Result<(), QueryValidationError>
106+
where
107+
T: graphql_parser::query::Text<'doc>,
108+
{
106109
// First, give ids to all fragments and operations.
107110
for definition in &query.definitions {
108111
match definition {
109112
graphql_parser::query::Definition::Fragment(fragment) => {
110113
let graphql_parser::query::TypeCondition::On(on) = &fragment.type_condition;
111114
resolved_query.fragments.push(ResolvedFragment {
112-
name: fragment.name.clone(),
113-
on: schema.find_type(on).ok_or_else(|| {
115+
name: fragment.name.as_ref().into(),
116+
on: schema.find_type(on.as_ref()).ok_or_else(|| {
114117
QueryValidationError::new(format!(
115118
"Could not find type {} for fragment {} in schema.",
116-
on, fragment.name
119+
on.as_ref(), fragment.name.as_ref()
117120
))
118121
})?,
119122
selection_set: Vec::new(),
@@ -130,7 +133,7 @@ fn create_roots(
130133
})?;
131134
let resolved_operation: ResolvedOperation = ResolvedOperation {
132135
object_id: on,
133-
name: m.name.as_ref().expect("mutation without name").to_owned(),
136+
name: m.name.as_ref().expect("mutation without name").as_ref().into(),
134137
_operation_type: operations::OperationType::Mutation,
135138
selection_set: Vec::with_capacity(m.selection_set.items.len()),
136139
};
@@ -142,7 +145,7 @@ fn create_roots(
142145
) => {
143146
let on = schema.query_type();
144147
let resolved_operation: ResolvedOperation = ResolvedOperation {
145-
name: q.name.as_ref().expect("query without name").to_owned(),
148+
name: q.name.as_ref().expect("query without name").as_ref().into(),
146149
_operation_type: operations::OperationType::Query,
147150
object_id: on,
148151
selection_set: Vec::with_capacity(q.selection_set.items.len()),
@@ -170,7 +173,8 @@ fn create_roots(
170173
.name
171174
.as_ref()
172175
.expect("subscription without name")
173-
.to_owned(),
176+
.as_ref()
177+
.into(),
174178
_operation_type: operations::OperationType::Subscription,
175179
object_id: on,
176180
selection_set: Vec::with_capacity(s.selection_set.items.len()),
@@ -191,25 +195,28 @@ fn create_roots(
191195
Ok(())
192196
}
193197

194-
fn resolve_fragment(
198+
fn resolve_fragment<'doc, T>(
195199
query: &mut Query,
196200
schema: &Schema,
197-
fragment_definition: &graphql_parser::query::FragmentDefinition,
198-
) -> Result<(), QueryValidationError> {
201+
fragment_definition: &graphql_parser::query::FragmentDefinition<'doc, T>,
202+
) -> Result<(), QueryValidationError>
203+
where
204+
T: graphql_parser::query::Text<'doc>,
205+
{
199206
let graphql_parser::query::TypeCondition::On(on) = &fragment_definition.type_condition;
200-
let on = schema.find_type(on).ok_or_else(|| {
207+
let on = schema.find_type(on.as_ref()).ok_or_else(|| {
201208
QueryValidationError::new(format!(
202209
"Could not find type `{}` referenced by fragment `{}`",
203-
on, fragment_definition.name
210+
on.as_ref(), fragment_definition.name.as_ref()
204211
))
205212
})?;
206213

207214
let (id, _) = query
208-
.find_fragment(&fragment_definition.name)
215+
.find_fragment(fragment_definition.name.as_ref())
209216
.ok_or_else(|| {
210217
QueryValidationError::new(format!(
211218
"Could not find fragment `{}`.",
212-
fragment_definition.name
219+
fragment_definition.name.as_ref()
213220
))
214221
})?;
215222

@@ -224,17 +231,20 @@ fn resolve_fragment(
224231
Ok(())
225232
}
226233

227-
fn resolve_union_selection(
234+
fn resolve_union_selection<'doc, T>(
228235
query: &mut Query,
229236
_union_id: UnionId,
230-
selection_set: &graphql_parser::query::SelectionSet,
237+
selection_set: &graphql_parser::query::SelectionSet<'doc, T>,
231238
parent: SelectionParent,
232239
schema: &Schema,
233-
) -> Result<(), QueryValidationError> {
240+
) -> Result<(), QueryValidationError>
241+
where
242+
T: graphql_parser::query::Text<'doc>,
243+
{
234244
for item in selection_set.items.iter() {
235245
match item {
236246
graphql_parser::query::Selection::Field(field) => {
237-
if field.name == TYPENAME_FIELD {
247+
if field.name.as_ref() == TYPENAME_FIELD {
238248
let id = query.push_selection(Selection::Typename, parent);
239249
parent.add_to_selection_set(query, id);
240250
} else {
@@ -250,11 +260,11 @@ fn resolve_union_selection(
250260
}
251261
graphql_parser::query::Selection::FragmentSpread(fragment_spread) => {
252262
let (fragment_id, _fragment) = query
253-
.find_fragment(&fragment_spread.fragment_name)
263+
.find_fragment(fragment_spread.fragment_name.as_ref())
254264
.ok_or_else(|| {
255265
QueryValidationError::new(format!(
256266
"Could not find fragment `{}` referenced by fragment spread.",
257-
fragment_spread.fragment_name
267+
fragment_spread.fragment_name.as_ref()
258268
))
259269
})?;
260270

@@ -268,35 +278,38 @@ fn resolve_union_selection(
268278
Ok(())
269279
}
270280

271-
fn resolve_object_selection<'a>(
281+
fn resolve_object_selection<'a, 'doc, T>(
272282
query: &mut Query,
273283
object: &dyn crate::schema::ObjectLike,
274-
selection_set: &graphql_parser::query::SelectionSet,
284+
selection_set: &graphql_parser::query::SelectionSet<'doc, T>,
275285
parent: SelectionParent,
276286
schema: &'a Schema,
277-
) -> Result<(), QueryValidationError> {
287+
) -> Result<(), QueryValidationError>
288+
where
289+
T: graphql_parser::query::Text<'doc>,
290+
{
278291
for item in selection_set.items.iter() {
279292
match item {
280293
graphql_parser::query::Selection::Field(field) => {
281-
if field.name == TYPENAME_FIELD {
294+
if field.name.as_ref() == TYPENAME_FIELD {
282295
let id = query.push_selection(Selection::Typename, parent);
283296
parent.add_to_selection_set(query, id);
284297
continue;
285298
}
286299

287300
let (field_id, schema_field) = object
288-
.get_field_by_name(&field.name, schema)
301+
.get_field_by_name(field.name.as_ref(), schema)
289302
.ok_or_else(|| {
290303
QueryValidationError::new(format!(
291304
"No field named {} on {}",
292-
&field.name,
305+
field.name.as_ref(),
293306
object.name()
294307
))
295308
})?;
296309

297310
let id = query.push_selection(
298311
Selection::Field(SelectedField {
299-
alias: field.alias.clone(),
312+
alias: field.alias.as_ref().map(|alias| alias.as_ref().into()),
300313
field_id,
301314
selection_set: Vec::with_capacity(selection_set.items.len()),
302315
}),
@@ -320,11 +333,11 @@ fn resolve_object_selection<'a>(
320333
}
321334
graphql_parser::query::Selection::FragmentSpread(fragment_spread) => {
322335
let (fragment_id, _fragment) = query
323-
.find_fragment(&fragment_spread.fragment_name)
336+
.find_fragment(fragment_spread.fragment_name.as_ref())
324337
.ok_or_else(|| {
325338
QueryValidationError::new(format!(
326339
"Could not find fragment `{}` referenced by fragment spread.",
327-
fragment_spread.fragment_name
340+
fragment_spread.fragment_name.as_ref()
328341
))
329342
})?;
330343

@@ -338,13 +351,16 @@ fn resolve_object_selection<'a>(
338351
Ok(())
339352
}
340353

341-
fn resolve_selection(
354+
fn resolve_selection<'doc, T>(
342355
ctx: &mut Query,
343356
on: TypeId,
344-
selection_set: &graphql_parser::query::SelectionSet,
357+
selection_set: &graphql_parser::query::SelectionSet<'doc, T>,
345358
parent: SelectionParent,
346359
schema: &Schema,
347-
) -> Result<(), QueryValidationError> {
360+
) -> Result<(), QueryValidationError>
361+
where
362+
T: graphql_parser::query::Text<'doc>,
363+
{
348364
match on {
349365
TypeId::Object(oid) => {
350366
let object = schema.get_object(oid);
@@ -370,20 +386,23 @@ fn resolve_selection(
370386
Ok(())
371387
}
372388

373-
fn resolve_inline_fragment(
389+
fn resolve_inline_fragment<'doc, T>(
374390
query: &mut Query,
375391
schema: &Schema,
376-
inline_fragment: &graphql_parser::query::InlineFragment,
392+
inline_fragment: &graphql_parser::query::InlineFragment<'doc, T>,
377393
parent: SelectionParent,
378-
) -> Result<SelectionId, QueryValidationError> {
394+
) -> Result<SelectionId, QueryValidationError>
395+
where
396+
T: graphql_parser::query::Text<'doc>,
397+
{
379398
let graphql_parser::query::TypeCondition::On(on) = inline_fragment
380399
.type_condition
381400
.as_ref()
382401
.expect("missing type condition on inline fragment");
383-
let type_id = schema.find_type(on).ok_or_else(|| {
402+
let type_id = schema.find_type(on.as_ref()).ok_or_else(|| {
384403
QueryValidationError::new(format!(
385404
"Could not find type `{}` referenced by inline fragment.",
386-
on
405+
on.as_ref()
387406
))
388407
})?;
389408

@@ -409,7 +428,7 @@ fn resolve_inline_fragment(
409428
fn resolve_operation(
410429
query: &mut Query,
411430
schema: &Schema,
412-
operation: &graphql_parser::query::OperationDefinition,
431+
operation: &graphql_parser::query::OperationDefinition<'static, String>,
413432
) -> Result<(), QueryValidationError> {
414433
match operation {
415434
graphql_parser::query::OperationDefinition::Mutation(m) => {
@@ -554,7 +573,7 @@ impl Query {
554573
pub(crate) struct ResolvedVariable {
555574
pub(crate) operation_id: OperationId,
556575
pub(crate) name: String,
557-
pub(crate) default: Option<graphql_parser::query::Value>,
576+
pub(crate) default: Option<graphql_parser::query::Value<'static, String>>,
558577
pub(crate) r#type: StoredFieldType,
559578
}
560579

@@ -622,17 +641,20 @@ impl UsedTypes {
622641
}
623642
}
624643

625-
fn resolve_variables(
644+
fn resolve_variables<'doc, T>(
626645
query: &mut Query,
627-
variables: &[graphql_parser::query::VariableDefinition],
646+
variables: &[graphql_parser::query::VariableDefinition<'doc, T>],
628647
schema: &Schema,
629648
operation_id: OperationId,
630-
) {
649+
)
650+
where
651+
T: graphql_parser::query::Text<'doc>,
652+
{
631653
for var in variables {
632654
query.variables.push(ResolvedVariable {
633655
operation_id,
634-
name: var.name.clone(),
635-
default: var.default_value.clone(),
656+
name: var.name.as_ref().into(),
657+
default: var.default_value.as_ref().map(|dflt| dflt.into_static()),
636658
r#type: resolve_field_type(schema, &var.var_type),
637659
});
638660
}

0 commit comments

Comments
 (0)