diff --git a/crates/apollo-compiler/CHANGELOG.md b/crates/apollo-compiler/CHANGELOG.md index 0fe032312..bc433cc89 100644 --- a/crates/apollo-compiler/CHANGELOG.md +++ b/crates/apollo-compiler/CHANGELOG.md @@ -21,12 +21,17 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## Features -- **Helper features for `Name` - [SimonSapin], [pull/???]:** +- **Helper features for `Name` and `Type` - [SimonSapin], [pull/739]:** * The `name!` macro also accepts an identifier: `name!(Query)` and `name!("Query")` create equivalent `Name` values. * `InvalidNameError` now contain a public `NodeStr` for the input string that is invalid, and implements `Display`, `Debug`, and `Error` traits. * Add `TryFrom` conversion to `Name` from `NodeStr`, `&NodeStr`, `&str`, `String`, and `&String`. + * Add a `ty!` macro to build a static `ast::Type` using GraphQL-like syntax. + +[SimonSapin]: https://github.com/SimonSapin +[pull/739]: https://github.com/apollographql/apollo-rs/pull/739 + # [1.0.0-beta.6](https://crates.io/crates/apollo-compiler/1.0.0-beta.6) - 2023-11-10 diff --git a/crates/apollo-compiler/src/ast/impls.rs b/crates/apollo-compiler/src/ast/impls.rs index 64d8414b1..1fbf84a69 100644 --- a/crates/apollo-compiler/src/ast/impls.rs +++ b/crates/apollo-compiler/src/ast/impls.rs @@ -534,6 +534,33 @@ impl VariableDefinition { serialize_method!(); } +/// Create a static [`Type`] with GraphQL-like syntax +/// +/// ``` +/// use apollo_compiler::ty; +/// +/// assert_eq!(ty!(Obj).to_string(), "Obj"); +/// assert_eq!(ty!(Obj!).to_string(), "Obj!"); +/// assert_eq!(ty!([Obj]).to_string(), "[Obj]"); +/// assert_eq!(ty!([Obj]!).to_string(), "[Obj]!"); +/// assert_eq!(ty!([[[Obj ] !]]!).to_string(), "[[[Obj]!]]!"); +/// ``` +#[macro_export] +macro_rules! ty { + ($name: ident) => { + $crate::ast::Type::Named($crate::name!($name)) + }; + ($name: ident !) => { + $crate::ast::Type::NonNullNamed($crate::name!($name)) + }; + ([ $($tt: tt)+ ]) => { + $crate::ast::Type::List(::std::boxed::Box::new($crate::ty!( $($tt)+ ))) + }; + ([ $($tt: tt)+ ]!) => { + $crate::ast::Type::NonNullList(::std::boxed::Box::new($crate::ty!( $($tt)+ ))) + }; +} + impl Type { /// Returns this type made non-null, if it isn’t already. pub fn non_null(self) -> Self { diff --git a/crates/apollo-compiler/src/executable/from_ast.rs b/crates/apollo-compiler/src/executable/from_ast.rs index c911d1686..b16bf0681 100644 --- a/crates/apollo-compiler/src/executable/from_ast.rs +++ b/crates/apollo-compiler/src/executable/from_ast.rs @@ -1,5 +1,5 @@ use super::*; -use crate::name; +use crate::ty; pub(crate) struct BuildErrors { pub(crate) errors: Vec, @@ -166,7 +166,7 @@ impl SelectionSet { description: None, name: ast.name.clone(), arguments: Vec::new(), - ty: Type::Named(name!("UNKNOWN")), + ty: ty!(UNKNOWN), directives: Default::default(), })) }; diff --git a/crates/apollo-compiler/src/schema/mod.rs b/crates/apollo-compiler/src/schema/mod.rs index f1e45b2e5..740cf5124 100644 --- a/crates/apollo-compiler/src/schema/mod.rs +++ b/crates/apollo-compiler/src/schema/mod.rs @@ -25,6 +25,7 @@ pub use crate::ast::{ InputValueDefinition, Name, NamedType, Type, Value, }; use crate::name; +use crate::ty; use crate::validation::DiagnosticList; /// High-level representation of a GraphQL schema @@ -485,7 +486,7 @@ impl Schema { description: None, name: name!("__typename"), arguments: Vec::new(), - ty: Type::Named(name!("String")).non_null(), + ty: ty!(String!), directives: ast::DirectiveList::new(), }), // __schema: __Schema! @@ -493,7 +494,7 @@ impl Schema { description: None, name: name!("__schema"), arguments: Vec::new(), - ty: Type::Named(name!("__Schema")).non_null(), + ty: ty!(__Schema!), directives: ast::DirectiveList::new(), }), // __type(name: String!): __Type @@ -503,12 +504,12 @@ impl Schema { arguments: vec![InputValueDefinition { description: None, name: name!("name"), - ty: ast::Type::Named(name!("String")).non_null().into(), + ty: ty!(String!).into(), default_value: None, directives: ast::DirectiveList::new(), } .into()], - ty: Type::Named(name!("__Type")), + ty: ty!(__Type), directives: ast::DirectiveList::new(), }), ] diff --git a/crates/apollo-compiler/tests/snapshot_tests.rs b/crates/apollo-compiler/tests/snapshot_tests.rs index a310d23c0..6cd127043 100644 --- a/crates/apollo-compiler/tests/snapshot_tests.rs +++ b/crates/apollo-compiler/tests/snapshot_tests.rs @@ -10,6 +10,7 @@ use apollo_compiler::ast; use apollo_compiler::name; use apollo_compiler::schema; +use apollo_compiler::ty; use apollo_compiler::DiagnosticList; use apollo_compiler::FileId; use apollo_compiler::Schema; @@ -266,7 +267,7 @@ fn test_invalid_synthetic_node() { description: Default::default(), name: name!("field"), arguments: Default::default(), - ty: schema::Type::Named(name!("UndefinedType")), + ty: ty!(UndefinedType), directives: Default::default(), } .into(),