Skip to content

Commit f066fca

Browse files
committed
Use borrowed names when constructing Type instances
1 parent 1f62b62 commit f066fca

27 files changed

+504
-469
lines changed

src/ast.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@ use parser::Spanning;
1313
/// This enum carries no semantic information and might refer to types that do
1414
/// not exist.
1515
#[derive(Clone, Eq, PartialEq, Debug)]
16-
pub enum Type {
16+
pub enum Type<'a> {
1717
/// A nullable named type, e.g. `String`
18-
Named(String),
18+
Named(&'a str),
1919
/// A nullable list type, e.g. `[String]`
2020
///
2121
/// The list itself is what's nullable, the containing type might be non-null.
22-
List(Box<Type>),
22+
List(Box<Type<'a>>),
2323
/// A non-null named type, e.g. `String!`
24-
NonNullNamed(String),
24+
NonNullNamed(&'a str),
2525
/// A non-null list type, e.g. `[String]!`.
2626
///
2727
/// The list itself is what's non-null, the containing type might be null.
28-
NonNullList(Box<Type>),
28+
NonNullList(Box<Type<'a>>),
2929
}
3030

3131
/// A JSON-like value that can be passed into the query execution, either
@@ -49,8 +49,8 @@ pub enum InputValue {
4949
}
5050

5151
#[derive(Clone, PartialEq, Debug)]
52-
pub struct VariableDefinition {
53-
pub var_type: Spanning<Type>,
52+
pub struct VariableDefinition<'a> {
53+
pub var_type: Spanning<Type<'a>>,
5454
pub default_value: Option<Spanning<InputValue>>,
5555
}
5656

@@ -60,8 +60,8 @@ pub struct Arguments {
6060
}
6161

6262
#[derive(Clone, PartialEq, Debug)]
63-
pub struct VariableDefinitions {
64-
pub items: Vec<(Spanning<String>, VariableDefinition)>,
63+
pub struct VariableDefinitions<'a> {
64+
pub items: Vec<(Spanning<String>, VariableDefinition<'a>)>,
6565
}
6666

6767
#[derive(Clone, PartialEq, Debug)]
@@ -122,10 +122,10 @@ pub enum OperationType {
122122
}
123123

124124
#[derive(Clone, PartialEq, Debug)]
125-
pub struct Operation {
125+
pub struct Operation<'a> {
126126
pub operation_type: OperationType,
127127
pub name: Option<Spanning<String>>,
128-
pub variable_definitions: Option<Spanning<VariableDefinitions>>,
128+
pub variable_definitions: Option<Spanning<VariableDefinitions<'a>>>,
129129
pub directives: Option<Vec<Spanning<Directive>>>,
130130
pub selection_set: Vec<Selection>,
131131
}
@@ -139,12 +139,12 @@ pub struct Fragment {
139139
}
140140

141141
#[derive(Clone, PartialEq, Debug)]
142-
pub enum Definition {
143-
Operation(Spanning<Operation>),
142+
pub enum Definition<'a> {
143+
Operation(Spanning<Operation<'a>>),
144144
Fragment(Spanning<Fragment>),
145145
}
146146

147-
pub type Document = Vec<Definition>;
147+
pub type Document<'a> = Vec<Definition<'a>>;
148148

149149
/// Parse an unstructured input value into a Rust data type.
150150
///
@@ -163,7 +163,7 @@ pub trait ToInputValue: Sized {
163163
fn to(&self) -> InputValue;
164164
}
165165

166-
impl Type {
166+
impl<'a> Type<'a> {
167167
/// Get the name of a named type.
168168
///
169169
/// Only applies to named types; lists will return `None`.
@@ -193,7 +193,7 @@ impl Type {
193193
}
194194
}
195195

196-
impl fmt::Display for Type {
196+
impl<'a> fmt::Display for Type<'a> {
197197
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
198198
match *self {
199199
Type::Named(ref n) => write!(f, "{}", n),
@@ -447,7 +447,7 @@ impl Arguments {
447447
}
448448
}
449449

450-
impl VariableDefinitions {
450+
impl<'a> VariableDefinitions<'a> {
451451
pub fn iter(&self) -> slice::Iter<(Spanning<String>, VariableDefinition)> {
452452
self.items.iter()
453453
}

src/executor.rs

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ use types::base::GraphQLType;
1919
/// The registry gathers metadata for all types in a schema. It provides
2020
/// convenience methods to convert types implementing the `GraphQLType` trait
2121
/// into `Type` instances and automatically registers them.
22-
pub struct Registry {
22+
pub struct Registry<'r> {
2323
/// Currently registered types
24-
pub types: HashMap<String, MetaType>,
24+
pub types: HashMap<String, MetaType<'r>>,
2525
}
2626

2727
#[derive(Clone)]
@@ -38,7 +38,7 @@ pub struct Executor<'a, CtxT> where CtxT: 'a {
3838
fragments: &'a HashMap<&'a str, &'a Fragment>,
3939
variables: &'a HashMap<String, InputValue>,
4040
current_selection_set: Option<&'a [Selection]>,
41-
schema: &'a SchemaType,
41+
schema: &'a SchemaType<'a>,
4242
context: &'a CtxT,
4343
errors: &'a RwLock<Vec<ExecutionError>>,
4444
field_path: FieldPath<'a>,
@@ -353,9 +353,9 @@ pub fn execute_validated_query<'a, QueryT, MutationT, CtxT>(
353353
Ok((value, errors))
354354
}
355355

356-
impl Registry {
356+
impl<'r> Registry<'r> {
357357
/// Construct a new registry
358-
pub fn new(types: HashMap<String, MetaType>) -> Registry {
358+
pub fn new(types: HashMap<String, MetaType<'r>>) -> Registry<'r> {
359359
Registry {
360360
types: types,
361361
}
@@ -365,10 +365,10 @@ impl Registry {
365365
///
366366
/// If the registry hasn't seen a type with this name before, it will
367367
/// construct its metadata and store it.
368-
pub fn get_type<T>(&mut self) -> Type where T: GraphQLType {
368+
pub fn get_type<T>(&mut self) -> Type<'r> where T: GraphQLType {
369369
if let Some(name) = T::name() {
370370
if !self.types.contains_key(name) {
371-
self.insert_placeholder(name, Type::NonNullNamed(name.to_owned()));
371+
self.insert_placeholder(name, Type::NonNullNamed(name));
372372
let meta = T::meta(self);
373373
self.types.insert(name.to_owned(), meta);
374374
}
@@ -380,7 +380,7 @@ impl Registry {
380380
}
381381

382382
/// Create a field with the provided name
383-
pub fn field<T>(&mut self, name: &str) -> Field where T: GraphQLType {
383+
pub fn field<T>(&mut self, name: &str) -> Field<'r> where T: GraphQLType {
384384
Field {
385385
name: name.to_owned(),
386386
description: None,
@@ -391,7 +391,7 @@ impl Registry {
391391
}
392392

393393
#[doc(hidden)]
394-
pub fn field_convert<'a, T: IntoResolvable<'a, I, C>, I, C>(&mut self, name: &str) -> Field
394+
pub fn field_convert<'a, T: IntoResolvable<'a, I, C>, I, C>(&mut self, name: &str) -> Field<'r>
395395
where I: GraphQLType
396396
{
397397
Field {
@@ -404,7 +404,7 @@ impl Registry {
404404
}
405405

406406
/// Create an argument with the provided name
407-
pub fn arg<T>(&mut self, name: &str) -> Argument where T: GraphQLType + FromInputValue {
407+
pub fn arg<T>(&mut self, name: &str) -> Argument<'r> where T: GraphQLType + FromInputValue {
408408
Argument::new(name, self.get_type::<T>())
409409
}
410410

@@ -417,14 +417,14 @@ impl Registry {
417417
name: &str,
418418
value: &T,
419419
)
420-
-> Argument
420+
-> Argument<'r>
421421
where T: GraphQLType + ToInputValue + FromInputValue
422422
{
423423
Argument::new(name, self.get_type::<Option<T>>())
424424
.default_value(value.to())
425425
}
426426

427-
fn insert_placeholder(&mut self, name: &str, of_type: Type) {
427+
fn insert_placeholder(&mut self, name: &str, of_type: Type<'r>) {
428428
if !self.types.contains_key(name) {
429429
self.types.insert(
430430
name.to_owned(),
@@ -435,22 +435,21 @@ impl Registry {
435435
/// Create a scalar meta type
436436
///
437437
/// This expects the type to implement `FromInputValue`.
438-
pub fn build_scalar_type<T>(&mut self)
439-
-> ScalarMeta
438+
pub fn build_scalar_type<T>(&mut self) -> ScalarMeta<'r>
440439
where T: FromInputValue + GraphQLType
441440
{
442441
let name = T::name().expect("Scalar types must be named. Implement name()");
443442
ScalarMeta::new::<T>(name)
444443
}
445444

446445
/// Create a list meta type
447-
pub fn build_list_type<T: GraphQLType>(&mut self) -> ListMeta {
446+
pub fn build_list_type<T: GraphQLType>(&mut self) -> ListMeta<'r> {
448447
let of_type = self.get_type::<T>();
449448
ListMeta::new(of_type)
450449
}
451450

452451
/// Create a nullable meta type
453-
pub fn build_nullable_type<T: GraphQLType>(&mut self) -> NullableMeta {
452+
pub fn build_nullable_type<T: GraphQLType>(&mut self) -> NullableMeta<'r> {
454453
let of_type = self.get_type::<T>();
455454
NullableMeta::new(of_type)
456455
}
@@ -459,62 +458,51 @@ impl Registry {
459458
///
460459
/// To prevent infinite recursion by enforcing ordering, this returns a
461460
/// function that needs to be called with the list of fields on the object.
462-
pub fn build_object_type<T>(&mut self)
463-
-> Box<Fn(&[Field]) -> ObjectMeta>
461+
pub fn build_object_type<T>(&mut self, fields: &[Field<'r>]) -> ObjectMeta<'r>
464462
where T: GraphQLType
465463
{
466464
let name = T::name().expect("Object types must be named. Implement name()");
467-
let typename_field = self.field::<String>("__typename");
468465

469-
Box::new(move |fs: &[Field]| {
470-
let mut v = fs.to_vec();
471-
v.push(typename_field.clone());
472-
ObjectMeta::new(name, &v)
473-
})
466+
let mut v = fields.to_vec();
467+
v.push(self.field::<String>("__typename"));
468+
ObjectMeta::new(name, &v)
474469
}
475470

476471
/// Create an enum meta type
477-
pub fn build_enum_type<T>(&mut self)
478-
-> Box<Fn(&[EnumValue]) -> EnumMeta>
472+
pub fn build_enum_type<T>(&mut self, values: &[EnumValue]) -> EnumMeta<'r>
479473
where T: FromInputValue + GraphQLType
480474
{
481475
let name = T::name().expect("Enum types must be named. Implement name()");
482476

483-
Box::new(move |values: &[EnumValue]| EnumMeta::new::<T>(name, values))
477+
EnumMeta::new::<T>(name, values)
484478
}
485479

486480
/// Create an interface meta type builder
487-
pub fn build_interface_type<T>(&mut self)
488-
-> Box<Fn(&[Field]) -> InterfaceMeta>
481+
pub fn build_interface_type<T>(&mut self, fields: &[Field<'r>]) -> InterfaceMeta<'r>
489482
where T: GraphQLType
490483
{
491484
let name = T::name().expect("Interface types must be named. Implement name()");
492-
let typename_field = self.field::<String>("__typename");
493485

494-
Box::new(move |fs: &[Field]| {
495-
let mut v = fs.to_vec();
496-
v.push(typename_field.clone());
497-
InterfaceMeta::new(name, &v)
498-
})
486+
let mut v = fields.to_vec();
487+
v.push(self.field::<String>("__typename"));
488+
InterfaceMeta::new(name, &v)
499489
}
500490

501491
/// Create a union meta type builder
502-
pub fn build_union_type<T>(&mut self)
503-
-> Box<Fn(&[Type]) -> UnionMeta>
492+
pub fn build_union_type<T>(&mut self, types: &[Type<'r>]) -> UnionMeta<'r>
504493
where T: GraphQLType
505494
{
506495
let name = T::name().expect("Union types must be named. Implement name()");
507496

508-
Box::new(move |ts: &[Type]| UnionMeta::new(name, ts))
497+
UnionMeta::new(name, types)
509498
}
510499

511500
/// Create an input object meta type builder
512-
pub fn build_input_object_type<T>(&mut self)
513-
-> Box<Fn(&[Argument]) -> InputObjectMeta>
501+
pub fn build_input_object_type<T>(&mut self, args: &[Argument<'r>]) -> InputObjectMeta<'r>
514502
where T: FromInputValue + GraphQLType
515503
{
516504
let name = T::name().expect("Input object types must be named. Implement name()");
517505

518-
Box::new(move |args: &[Argument]| InputObjectMeta::new::<T>(name, args))
506+
InputObjectMeta::new::<T>(name, args)
519507
}
520508
}

src/integrations/iron_handlers.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,23 @@ use ::{InputValue, GraphQLType, RootNode, execute};
2222
/// this endpoint containing the field `"query"` and optionally `"variables"`.
2323
/// The variables should be a JSON object containing the variable to value
2424
/// mapping.
25-
pub struct GraphQLHandler<CtxFactory, Query, Mutation, CtxT>
25+
pub struct GraphQLHandler<'a, CtxFactory, Query, Mutation, CtxT>
2626
where CtxFactory: Fn(&mut Request) -> CtxT + Send + Sync + 'static,
2727
CtxT: 'static,
2828
Query: GraphQLType<Context=CtxT> + Send + Sync + 'static,
2929
Mutation: GraphQLType<Context=CtxT> + Send + Sync + 'static,
3030
{
3131
context_factory: CtxFactory,
32-
root_node: RootNode<Query, Mutation>,
32+
root_node: RootNode<'a, Query, Mutation>,
3333
}
3434

3535
/// Handler that renders GraphiQL - a graphical query editor interface
3636
pub struct GraphiQLHandler {
3737
graphql_url: String,
3838
}
3939

40-
impl<CtxFactory, Query, Mutation, CtxT>
41-
GraphQLHandler<CtxFactory, Query, Mutation, CtxT>
40+
impl<'a, CtxFactory, Query, Mutation, CtxT>
41+
GraphQLHandler<'a, CtxFactory, Query, Mutation, CtxT>
4242
where CtxFactory: Fn(&mut Request) -> CtxT + Send + Sync + 'static,
4343
CtxT: 'static,
4444
Query: GraphQLType<Context=CtxT> + Send + Sync + 'static,
@@ -145,13 +145,13 @@ impl GraphiQLHandler {
145145
}
146146
}
147147

148-
impl<CtxFactory, Query, Mutation, CtxT>
148+
impl<'a, CtxFactory, Query, Mutation, CtxT>
149149
Handler
150-
for GraphQLHandler<CtxFactory, Query, Mutation, CtxT>
150+
for GraphQLHandler<'a, CtxFactory, Query, Mutation, CtxT>
151151
where CtxFactory: Fn(&mut Request) -> CtxT + Send + Sync + 'static,
152152
CtxT: 'static,
153153
Query: GraphQLType<Context=CtxT> + Send + Sync + 'static,
154-
Mutation: GraphQLType<Context=CtxT> + Send + Sync + 'static,
154+
Mutation: GraphQLType<Context=CtxT> + Send + Sync + 'static, 'a: 'static,
155155
{
156156
fn handle(&self, req: &mut Request) -> IronResult<Response> {
157157
match req.method {

src/macros/enums.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ macro_rules! graphql_enum {
6666
Some(graphql_enum!(@as_expr, $outname))
6767
}
6868

69-
fn meta(registry: &mut $crate::Registry) -> $crate::meta::MetaType {
69+
fn meta<'r>(registry: &mut $crate::Registry<'r>) -> $crate::meta::MetaType<'r> {
7070
graphql_enum!(
7171
@maybe_apply, $descr, description,
72-
registry.build_enum_type::<$name>()(&[
72+
registry.build_enum_type::<$name>(&[
7373
$(
7474
graphql_enum!(
7575
@maybe_apply,

src/macros/input_object.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,11 @@ macro_rules! graphql_input_object {
155155
Some($outname)
156156
}
157157

158-
fn meta(registry: &mut $crate::Registry) -> $crate::meta::MetaType {
158+
fn meta<'r>(registry: &mut $crate::Registry<'r>) -> $crate::meta::MetaType<'r> {
159+
let fields = graphql_input_object!(@generate_meta_fields, registry, $fields);
159160
graphql_input_object!(
160161
@maybe_apply, $descr, description,
161-
registry.build_input_object_type::<$name>()(
162-
graphql_input_object!(@generate_meta_fields, registry, $fields)
163-
)).into_meta()
162+
registry.build_input_object_type::<$name>(fields)).into_meta()
164163
}
165164
}
166165
};

src/macros/interface.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,11 @@ macro_rules! graphql_interface {
236236

237237
#[allow(unused_assignments)]
238238
#[allow(unused_mut)]
239-
fn meta(registry: &mut $crate::Registry) -> $crate::meta::MetaType {
239+
fn meta<'r>(registry: &mut $crate::Registry<'r>) -> $crate::meta::MetaType<'r> {
240240
let mut fields = Vec::new();
241241
let mut description = None;
242242
graphql_interface!(@ gather_meta, (registry, fields, description), $($items)*);
243-
let mut mt = registry.build_interface_type::<$name>()(&fields);
243+
let mut mt = registry.build_interface_type::<$name>(&fields);
244244

245245
if let Some(description) = description {
246246
mt = mt.description(description);

0 commit comments

Comments
 (0)