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 ;
2
4
3
5
use crate :: parser:: { SourcePosition , Spanning } ;
4
6
@@ -16,76 +18,98 @@ pub struct Lexer<'a> {
16
18
///
17
19
/// This is only used for tagging how the lexer has interpreted a value literal
18
20
#[ expect( missing_docs, reason = "self-explanatory" ) ]
19
- #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
21
+ #[ derive( Clone , Copy , Debug , Display , Eq , PartialEq ) ]
20
22
pub enum ScalarToken < ' a > {
23
+ #[ display( "\" {}\" " , _0. replace( '\\' , "\\ \\ " ) . replace( '"' , "\\ \" " ) ) ]
21
24
String ( & ' a str ) ,
22
25
Float ( & ' a str ) ,
23
26
Int ( & ' a str ) ,
24
27
}
25
28
26
29
/// A single token in the input source
27
30
#[ expect( missing_docs, reason = "self-explanatory" ) ]
28
- #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
31
+ #[ derive( Clone , Copy , Debug , Display , Eq , PartialEq ) ]
29
32
pub enum Token < ' a > {
30
33
Name ( & ' a str ) ,
31
34
Scalar ( ScalarToken < ' a > ) ,
35
+ #[ display( "!" ) ]
32
36
ExclamationMark ,
37
+ #[ display( "$" ) ]
33
38
Dollar ,
39
+ #[ display( "(" ) ]
34
40
ParenOpen ,
41
+ #[ display( ")" ) ]
35
42
ParenClose ,
43
+ #[ display( "[" ) ]
36
44
BracketOpen ,
45
+ #[ display( "]" ) ]
37
46
BracketClose ,
47
+ #[ display( "{{" ) ]
38
48
CurlyOpen ,
49
+ #[ display( "}}" ) ]
39
50
CurlyClose ,
51
+ #[ display( "..." ) ]
40
52
Ellipsis ,
53
+ #[ display( ":" ) ]
41
54
Colon ,
55
+ #[ display( "=" ) ]
42
56
Equals ,
57
+ #[ display( "@" ) ]
43
58
At ,
59
+ #[ display( "|" ) ]
44
60
Pipe ,
61
+ #[ display( "End of file" ) ]
45
62
EndOfFile ,
46
63
}
47
64
48
65
/// Error when tokenizing the input source
49
- #[ derive( Clone , Debug , PartialEq , Eq ) ]
66
+ #[ derive( Clone , Debug , Display , Eq , PartialEq ) ]
50
67
pub enum LexerError {
51
68
/// An unknown character was found
52
69
///
53
70
/// Unknown characters are characters that do not occur anywhere in the
54
71
/// GraphQL language, such as `?` or `%`.
72
+ #[ display( "Unknown character \" {_0}\" " ) ]
55
73
UnknownCharacter ( char ) ,
56
74
57
75
/// An unexpected character was found
58
76
///
59
77
/// Unexpected characters are characters that _do_ exist in the GraphQL
60
78
/// language, but is not expected at the current position in the document.
79
+ #[ display( "Unexpected character \" {_0}\" " ) ]
61
80
UnexpectedCharacter ( char ) ,
62
81
63
82
/// An unterminated string literal was found
64
83
///
65
84
/// Apart from forgetting the ending `"`, terminating a string within a
66
85
/// Unicode escape sequence or having a line break in the string also
67
86
/// causes this error.
87
+ #[ display( "Unterminated string literal" ) ]
68
88
UnterminatedString ,
69
89
70
90
/// An unknown character in a string literal was found
71
91
///
72
92
/// This occurs when an invalid source character is found in a string
73
93
/// literal, such as ASCII control characters.
94
+ #[ display( "Unknown character \" {_0}\" in string literal" ) ]
74
95
UnknownCharacterInString ( char ) ,
75
96
76
97
/// An unknown escape sequence in a string literal was found
77
98
///
78
99
/// Only a limited set of escape sequences are supported, this is emitted
79
100
/// when e.g. `"\l"` is parsed.
101
+ #[ display( "Unknown escape sequence \" {_0}\" in string" ) ]
80
102
UnknownEscapeSequence ( String ) ,
81
103
82
104
/// The input source was unexpectedly terminated
83
105
///
84
106
/// Emitted when the current token requires a succeeding character, but
85
107
/// the source has reached EOF. Emitted when scanning e.g. `"1."`.
108
+ #[ display( "Unexpected end of input" ) ]
86
109
UnexpectedEndOfFile ,
87
110
88
111
/// An invalid number literal was found
112
+ #[ display( "Invalid number literal" ) ]
89
113
InvalidNumber ,
90
114
}
91
115
@@ -477,34 +501,6 @@ impl<'a> Iterator for Lexer<'a> {
477
501
}
478
502
}
479
503
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
-
508
504
fn is_source_char ( c : char ) -> bool {
509
505
c == '\t' || c == '\n' || c == '\r' || c >= ' '
510
506
}
@@ -521,22 +517,4 @@ fn is_number_start(c: char) -> bool {
521
517
c == '-' || c. is_ascii_digit ( )
522
518
}
523
519
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
-
542
520
impl std:: error:: Error for LexerError { }
0 commit comments