1- use std:: { char, fmt, iter:: Peekable , str:: CharIndices } ;
1+ use std:: { char, iter:: Peekable , str:: CharIndices } ;
2+
3+ use derive_more:: with_trait:: Display ;
24
35use crate :: parser:: { SourcePosition , Spanning } ;
46
@@ -16,76 +18,98 @@ pub struct Lexer<'a> {
1618///
1719/// This is only used for tagging how the lexer has interpreted a value literal
1820#[ expect( missing_docs, reason = "self-explanatory" ) ]
19- #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
21+ #[ derive( Clone , Copy , Debug , Display , Eq , PartialEq ) ]
2022pub enum ScalarToken < ' a > {
23+ #[ display( "\" {}\" " , _0. replace( '\\' , "\\ \\ " ) . replace( '"' , "\\ \" " ) ) ]
2124 String ( & ' a str ) ,
2225 Float ( & ' a str ) ,
2326 Int ( & ' a str ) ,
2427}
2528
2629/// A single token in the input source
2730#[ expect( missing_docs, reason = "self-explanatory" ) ]
28- #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
31+ #[ derive( Clone , Copy , Debug , Display , Eq , PartialEq ) ]
2932pub enum Token < ' a > {
3033 Name ( & ' a str ) ,
3134 Scalar ( ScalarToken < ' a > ) ,
35+ #[ display( "!" ) ]
3236 ExclamationMark ,
37+ #[ display( "$" ) ]
3338 Dollar ,
39+ #[ display( "(" ) ]
3440 ParenOpen ,
41+ #[ display( ")" ) ]
3542 ParenClose ,
43+ #[ display( "[" ) ]
3644 BracketOpen ,
45+ #[ display( "]" ) ]
3746 BracketClose ,
47+ #[ display( "{{" ) ]
3848 CurlyOpen ,
49+ #[ display( "}}" ) ]
3950 CurlyClose ,
51+ #[ display( "..." ) ]
4052 Ellipsis ,
53+ #[ display( ":" ) ]
4154 Colon ,
55+ #[ display( "=" ) ]
4256 Equals ,
57+ #[ display( "@" ) ]
4358 At ,
59+ #[ display( "|" ) ]
4460 Pipe ,
61+ #[ display( "End of file" ) ]
4562 EndOfFile ,
4663}
4764
4865/// Error when tokenizing the input source
49- #[ derive( Clone , Debug , PartialEq , Eq ) ]
66+ #[ derive( Clone , Debug , Display , Eq , PartialEq ) ]
5067pub enum LexerError {
5168 /// An unknown character was found
5269 ///
5370 /// Unknown characters are characters that do not occur anywhere in the
5471 /// GraphQL language, such as `?` or `%`.
72+ #[ display( "Unknown character \" {_0}\" " ) ]
5573 UnknownCharacter ( char ) ,
5674
5775 /// An unexpected character was found
5876 ///
5977 /// Unexpected characters are characters that _do_ exist in the GraphQL
6078 /// language, but is not expected at the current position in the document.
79+ #[ display( "Unexpected character \" {_0}\" " ) ]
6180 UnexpectedCharacter ( char ) ,
6281
6382 /// An unterminated string literal was found
6483 ///
6584 /// Apart from forgetting the ending `"`, terminating a string within a
6685 /// Unicode escape sequence or having a line break in the string also
6786 /// causes this error.
87+ #[ display( "Unterminated string literal" ) ]
6888 UnterminatedString ,
6989
7090 /// An unknown character in a string literal was found
7191 ///
7292 /// This occurs when an invalid source character is found in a string
7393 /// literal, such as ASCII control characters.
94+ #[ display( "Unknown character \" {_0}\" in string literal" ) ]
7495 UnknownCharacterInString ( char ) ,
7596
7697 /// An unknown escape sequence in a string literal was found
7798 ///
7899 /// Only a limited set of escape sequences are supported, this is emitted
79100 /// when e.g. `"\l"` is parsed.
101+ #[ display( "Unknown escape sequence \" {_0}\" in string" ) ]
80102 UnknownEscapeSequence ( String ) ,
81103
82104 /// The input source was unexpectedly terminated
83105 ///
84106 /// Emitted when the current token requires a succeeding character, but
85107 /// the source has reached EOF. Emitted when scanning e.g. `"1."`.
108+ #[ display( "Unexpected end of input" ) ]
86109 UnexpectedEndOfFile ,
87110
88111 /// An invalid number literal was found
112+ #[ display( "Invalid number literal" ) ]
89113 InvalidNumber ,
90114}
91115
@@ -477,34 +501,6 @@ impl<'a> Iterator for Lexer<'a> {
477501 }
478502}
479503
480- impl fmt:: Display for Token < ' _ > {
481- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
482- match * self {
483- Token :: Name ( name) => write ! ( f, "{name}" ) ,
484- Token :: Scalar ( ScalarToken :: Int ( s) ) | Token :: Scalar ( ScalarToken :: Float ( s) ) => {
485- write ! ( f, "{s}" )
486- }
487- Token :: Scalar ( ScalarToken :: String ( s) ) => {
488- write ! ( f, "\" {}\" " , s. replace( '\\' , "\\ \\ " ) . replace( '"' , "\\ \" " ) )
489- }
490- Token :: ExclamationMark => write ! ( f, "!" ) ,
491- Token :: Dollar => write ! ( f, "$" ) ,
492- Token :: ParenOpen => write ! ( f, "(" ) ,
493- Token :: ParenClose => write ! ( f, ")" ) ,
494- Token :: BracketOpen => write ! ( f, "[" ) ,
495- Token :: BracketClose => write ! ( f, "]" ) ,
496- Token :: CurlyOpen => write ! ( f, "{{" ) ,
497- Token :: CurlyClose => write ! ( f, "}}" ) ,
498- Token :: Ellipsis => write ! ( f, "..." ) ,
499- Token :: Colon => write ! ( f, ":" ) ,
500- Token :: Equals => write ! ( f, "=" ) ,
501- Token :: At => write ! ( f, "@" ) ,
502- Token :: Pipe => write ! ( f, "|" ) ,
503- Token :: EndOfFile => write ! ( f, "End of file" ) ,
504- }
505- }
506- }
507-
508504fn is_source_char ( c : char ) -> bool {
509505 c == '\t' || c == '\n' || c == '\r' || c >= ' '
510506}
@@ -521,22 +517,4 @@ fn is_number_start(c: char) -> bool {
521517 c == '-' || c. is_ascii_digit ( )
522518}
523519
524- impl fmt:: Display for LexerError {
525- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
526- match * self {
527- LexerError :: UnknownCharacter ( c) => write ! ( f, "Unknown character \" {c}\" " ) ,
528- LexerError :: UnterminatedString => write ! ( f, "Unterminated string literal" ) ,
529- LexerError :: UnknownCharacterInString ( c) => {
530- write ! ( f, "Unknown character \" {c}\" in string literal" )
531- }
532- LexerError :: UnknownEscapeSequence ( ref s) => {
533- write ! ( f, "Unknown escape sequence \" {s}\" in string" )
534- }
535- LexerError :: UnexpectedCharacter ( c) => write ! ( f, "Unexpected character \" {c}\" " ) ,
536- LexerError :: UnexpectedEndOfFile => write ! ( f, "Unexpected end of input" ) ,
537- LexerError :: InvalidNumber => write ! ( f, "Invalid number literal" ) ,
538- }
539- }
540- }
541-
542520impl std:: error:: Error for LexerError { }
0 commit comments