@@ -4,6 +4,7 @@ Defines error types used by the crate.
4
4
use std:: error:: Error ;
5
5
use std:: fmt;
6
6
use std:: io;
7
+ use std:: num:: { ParseFloatError , ParseIntError } ;
7
8
use input:: Cursor ;
8
9
9
10
/**
@@ -63,10 +64,10 @@ impl<'a> ScanError<'a> {
63
64
}
64
65
65
66
/**
66
- Shorthand for constructing a `Missing ` error.
67
+ Shorthand for constructing a `Syntax ` error.
67
68
*/
68
- pub fn missing ( at : Cursor < ' a > ) -> Self {
69
- Self :: new ( at, ScanErrorKind :: Missing )
69
+ pub fn syntax ( at : Cursor < ' a > , desc : & ' static str ) -> Self {
70
+ Self :: new ( at, ScanErrorKind :: Syntax ( desc ) )
70
71
}
71
72
72
73
/**
@@ -126,17 +127,34 @@ pub enum ScanErrorKind {
126
127
/// Failed to match a literal pattern term.
127
128
LiteralMismatch ,
128
129
129
- /// Scanning a value failed in some vague fashion.
130
- Missing ,
130
+ /// General syntax error.
131
+ Syntax ( & ' static str ) ,
132
+
133
+ /**
134
+ General syntax error.
135
+
136
+ Due to [Rust issue #26448](https://github.com/rust-lang/rust/issues/26448), some scanners which want to return a `Syntax` error *cannot*.
137
+ */
138
+ SyntaxNoMessage ,
131
139
132
140
/// Expected end-of-input.
133
141
ExpectedEnd ,
134
142
143
+ /// Floating point parsing failed.
144
+ Float ( ParseFloatError ) ,
145
+
146
+ /// Integer parsing failed.
147
+ Int ( ParseIntError ) ,
148
+
135
149
/// An IO error occurred.
136
150
Io ( io:: Error ) ,
137
151
138
152
/// Some other error occurred.
139
153
Other ( Box < Error > ) ,
154
+
155
+ /// Hidden variant to prevent exhaustive matching.
156
+ #[ doc( hidden) ]
157
+ __DoNotMatch,
140
158
}
141
159
142
160
impl ScanErrorKind {
@@ -153,10 +171,18 @@ impl fmt::Display for ScanErrorKind {
153
171
use self :: ScanErrorKind :: * ;
154
172
match * self {
155
173
LiteralMismatch => "did not match literal" . fmt ( fmt) ,
156
- Missing => "missing scannable input" . fmt ( fmt) ,
174
+ Syntax ( desc) => {
175
+ try!( "syntax error: " . fmt ( fmt) ) ;
176
+ try!( desc. fmt ( fmt) ) ;
177
+ Ok ( ( ) )
178
+ } ,
179
+ SyntaxNoMessage => "unknown syntax error" . fmt ( fmt) ,
157
180
ExpectedEnd => "expected end of input" . fmt ( fmt) ,
181
+ Float ( ref err) => err. fmt ( fmt) ,
182
+ Int ( ref err) => err. fmt ( fmt) ,
158
183
Io ( ref err) => err. fmt ( fmt) ,
159
184
Other ( ref err) => err. fmt ( fmt) ,
185
+ __DoNotMatch => panic ! ( "do not use ScanErrorKind::__DoNotMatch!" ) ,
160
186
}
161
187
}
162
188
}
@@ -165,22 +191,31 @@ impl Error for ScanErrorKind {
165
191
fn cause ( & self ) -> Option < & Error > {
166
192
use self :: ScanErrorKind :: * ;
167
193
match * self {
168
- LiteralMismatch => None ,
169
- Missing => None ,
170
- ExpectedEnd => None ,
194
+ LiteralMismatch
195
+ | Syntax ( _)
196
+ | SyntaxNoMessage
197
+ | ExpectedEnd
198
+ => None ,
199
+ Float ( ref err) => err. cause ( ) ,
200
+ Int ( ref err) => err. cause ( ) ,
171
201
Io ( ref err) => err. cause ( ) ,
172
202
Other ( ref err) => err. cause ( ) ,
203
+ __DoNotMatch => panic ! ( "do not use ScanErrorKind::__DoNotMatch!" ) ,
173
204
}
174
205
}
175
206
176
207
fn description ( & self ) -> & str {
177
208
use self :: ScanErrorKind :: * ;
178
209
match * self {
179
210
LiteralMismatch => "did not match literal" ,
180
- Missing => "missing scannable input" ,
211
+ Syntax ( _) => "syntax error" ,
212
+ SyntaxNoMessage => "unknown syntax error" ,
181
213
ExpectedEnd => "expected end of input" ,
214
+ Float ( ref err) => err. description ( ) ,
215
+ Int ( ref err) => err. description ( ) ,
182
216
Io ( ref err) => err. description ( ) ,
183
217
Other ( ref err) => err. description ( ) ,
218
+ __DoNotMatch => panic ! ( "do not use ScanErrorKind::__DoNotMatch!" ) ,
184
219
}
185
220
}
186
221
}
0 commit comments