Repository: Shopify/bluejay (language: rust)

Issue:
Parse error for enum value definitions `true`, `false`, and `null`
Per the [spec](https://spec.graphql.org/draft/#sel-HAFdTDCAEAAAAEBCAE8oE) enum values must be:
> _Name_ but not `true` or `false` or `null`

We should return a parse error when parsing enum value definitions where the name is invalid


Discussion / hints:

Fix patch:
diff --git a/bluejay-parser/src/ast/definition/enum_value_definition.rs b/bluejay-parser/src/ast/definition/enum_value_definition.rs
index a9ef7b7..761f933 100644
--- a/bluejay-parser/src/ast/definition/enum_value_definition.rs
+++ b/bluejay-parser/src/ast/definition/enum_value_definition.rs
@@ -1,8 +1,11 @@
-use crate::ast::{
-    definition::{Context, Directives},
-    ConstDirectives, FromTokens, ParseError, Tokens, TryFromTokens,
-};
 use crate::lexical_token::{Name, StringValue};
+use crate::{
+    ast::{
+        definition::{Context, Directives},
+        ConstDirectives, FromTokens, ParseError, Tokens, TryFromTokens,
+    },
+    HasSpan,
+};
 use bluejay_core::definition::{EnumValueDefinition as CoreEnumValueDefinition, HasDirectives};
 
 #[derive(Debug)]
@@ -32,6 +35,13 @@ impl<'a, C: Context> FromTokens<'a> for EnumValueDefinition<'a, C> {
     fn from_tokens(tokens: &mut impl Tokens<'a>) -> Result<Self, ParseError> {
         let description = tokens.next_if_string_value();
         let name = tokens.expect_name()?;
+        if matches!(name.as_str(), "null" | "true" | "false") {
+            return Err(ParseError::InvalidEnumValue {
+                span: name.span().clone(),
+                value: name.as_str().to_string(),
+            });
+        }
+
         let directives = ConstDirectives::try_from_tokens(tokens).transpose()?;
         Ok(Self {
             description,
diff --git a/bluejay-parser/src/ast/parse_error.rs b/bluejay-parser/src/ast/parse_error.rs
index dd826cc..880142f 100644
--- a/bluejay-parser/src/ast/parse_error.rs
+++ b/bluejay-parser/src/ast/parse_error.rs
@@ -3,6 +3,10 @@ use crate::Span;
 
 #[derive(Debug)]
 pub enum ParseError {
+    InvalidEnumValue {
+        span: Span,
+        value: String,
+    },
     ExpectedOneOf {
         span: Span,
         values: &'static [&'static str],
@@ -26,6 +30,14 @@ pub enum ParseError {
 impl From<ParseError> for Error {
     fn from(val: ParseError) -> Self {
         match val {
+            ParseError::InvalidEnumValue { span, value } => Self::new(
+                "Parse error",
+                Some(Annotation::new(
+                    format!("{value} is not an allowed enum value"),
+                    span,
+                )),
+                Vec::new(),
+            ),
             ParseError::ExpectedOneOf { span, values } => Self::new(
                 "Parse error",
                 Some(Annotation::new(


Test patch:
diff --git a/bluejay-parser/tests/snapshots/schema_definition_integration_test__error@reserved_keyword_enum_value.graphql.snap b/bluejay-parser/tests/snapshots/schema_definition_integration_test__error@reserved_keyword_enum_value.graphql.snap
new file mode 100644
index 0000000..294fe82
--- /dev/null
+++ b/bluejay-parser/tests/snapshots/schema_definition_integration_test__error@reserved_keyword_enum_value.graphql.snap
@@ -0,0 +1,12 @@
+---
+source: bluejay-parser/tests/schema_definition_integration_test.rs
+expression: formatted_errors
+input_file: bluejay-parser/tests/test_data/schema_definition/error/reserved_keyword_enum_value.graphql
+---
+Error: Parse error
+   ╭─[<unknown>:2:3]
+   │
+ 2 │   true
+   │   ──┬─  
+   │     ╰─── true is not an allowed enum value
+───╯
diff --git a/bluejay-parser/tests/test_data/schema_definition/error/reserved_keyword_enum_value.graphql b/bluejay-parser/tests/test_data/schema_definition/error/reserved_keyword_enum_value.graphql
new file mode 100644
index 0000000..ede8c0c
--- /dev/null
+++ b/bluejay-parser/tests/test_data/schema_definition/error/reserved_keyword_enum_value.graphql
@@ -0,0 +1,7 @@
+enum Test {
+  true
+}
+
+schema {
+  query: Test
+}