initial support for more full error messages

This commit is contained in:
Erick Tryzelaar
2014-08-03 12:35:15 -07:00
parent 499638eccd
commit d689bc8b85
8 changed files with 198 additions and 132 deletions
+35 -9
View File
@@ -320,7 +320,7 @@ fn deserialize_struct(
match $token { match $token {
::serde::de::StructStart(_, _) => $struct_block, ::serde::de::StructStart(_, _) => $struct_block,
::serde::de::MapStart(_) => $map_block, ::serde::de::MapStart(_) => $map_block,
_ => $deserializer.syntax_error(), token => $deserializer.syntax_error(token),
} }
) )
} }
@@ -383,6 +383,7 @@ fn deserialize_struct_from_map(
$name = Some( $name = Some(
try!(::serde::de::Deserializable::deserialize($deserializer)) try!(::serde::de::Deserializable::deserialize($deserializer))
); );
false
}) })
}) })
.collect(); .collect();
@@ -414,6 +415,25 @@ fn deserialize_struct_from_map(
.collect() .collect()
); );
let error_arms: Vec<ast::Arm> = fields.iter()
.map(|&(name, span)| {
let pats = fields.iter()
.map(|&(n, _)| {
if n == name {
quote_pat!(cx, None)
} else {
quote_pat!(cx, _)
}
})
.collect();
let pat = cx.pat_tuple(span, pats);
let s = cx.expr_str(span, token::get_ident(name));
quote_arm!(cx, $pat => { return $deserializer.missing_field_error($s); })
})
.collect();
quote_expr!(cx, { quote_expr!(cx, {
$let_fields $let_fields
@@ -423,21 +443,27 @@ fn deserialize_struct_from_map(
token => token, token => token,
}; };
let key = match token { let error = {
::serde::de::Str(s) => s, let key = match token {
::serde::de::String(ref s) => s.as_slice(), ::serde::de::Str(s) => s,
_ => { return $deserializer.syntax_error(); } ::serde::de::String(ref s) => s.as_slice(),
token => { return $deserializer.syntax_error(token); }
};
match key {
$key_arms
_ => true
}
}; };
match key { if error {
$key_arms return $deserializer.syntax_error(token);
_ => { return $deserializer.syntax_error(); }
} }
} }
let result = match $fields_tuple { let result = match $fields_tuple {
$fields_pat => $result, $fields_pat => $result,
_ => { return $deserializer.syntax_error(); } $error_arms
}; };
Ok(result) Ok(result)
+12 -8
View File
@@ -126,8 +126,7 @@ mod deserializer {
use super::{Error, EndOfStream, SyntaxError}; use super::{Error, EndOfStream, SyntaxError};
use de::Deserializer; use de;
use de::{Token, Int, SeqStart, Sep, End};
#[deriving(Eq, Show)] #[deriving(Eq, Show)]
enum State { enum State {
@@ -153,22 +152,22 @@ mod deserializer {
} }
} }
impl Iterator<Result<Token, Error>> for BytesDeserializer { impl Iterator<Result<de::Token, Error>> for BytesDeserializer {
#[inline] #[inline]
fn next(&mut self) -> Option<Result<Token, Error>> { fn next(&mut self) -> Option<Result<Token, Error>> {
match self.state { match self.state {
StartState => { StartState => {
self.state = SepOrEndState; self.state = SepOrEndState;
Some(Ok(SeqStart(self.len))) Some(Ok(de::SeqStart(self.len)))
} }
SepOrEndState => { SepOrEndState => {
match self.iter.next() { match self.iter.next() {
Some(value) => { Some(value) => {
Some(Ok(Int(value))) Some(Ok(de::Int(value)))
} }
None => { None => {
self.state = EndState; self.state = EndState;
Some(Ok(End)) Some(Ok(de::End))
} }
} }
} }
@@ -179,14 +178,19 @@ mod deserializer {
} }
} }
impl Deserializer<Error> for BytesDeserializer { impl de::Deserializer<Error> for BytesDeserializer {
#[inline] #[inline]
fn end_of_stream_error<T>(&self) -> Result<T, Error> { fn end_of_stream_error<T>(&self) -> Result<T, Error> {
Err(EndOfStream) Err(EndOfStream)
} }
#[inline] #[inline]
fn syntax_error<T>(&self) -> Result<T, Error> { fn syntax_error<T>(&self, _token: de::Token) -> Result<T, Error> {
Err(SyntaxError)
}
#[inline]
fn missing_field_error(&mut self, _field: &'static str) -> Error {
Err(SyntaxError) Err(SyntaxError)
} }
} }
+15 -11
View File
@@ -178,8 +178,7 @@ mod decoder {
mod deserializer { mod deserializer {
use super::{Animal, Dog, Frog, Error, EndOfStream, SyntaxError}; use super::{Animal, Dog, Frog, Error, EndOfStream, SyntaxError};
use de::Deserializer; use de;
use de::{Token, Int, String, EnumStart, End};
enum State { enum State {
AnimalState(Animal), AnimalState(Animal),
@@ -202,42 +201,47 @@ mod deserializer {
} }
} }
impl Iterator<Result<Token, Error>> for AnimalDeserializer { impl Iterator<Result<de::Token, Error>> for AnimalDeserializer {
#[inline] #[inline]
fn next(&mut self) -> Option<Result<Token, Error>> { fn next(&mut self) -> Option<Result<de::Token, Error>> {
match self.stack.pop() { match self.stack.pop() {
Some(AnimalState(Dog)) => { Some(AnimalState(Dog)) => {
self.stack.push(EndState); self.stack.push(EndState);
Some(Ok(EnumStart("Animal", "Dog", 0))) Some(Ok(de::EnumStart("Animal", "Dog", 0)))
} }
Some(AnimalState(Frog(x0, x1))) => { Some(AnimalState(Frog(x0, x1))) => {
self.stack.push(EndState); self.stack.push(EndState);
self.stack.push(IntState(x1)); self.stack.push(IntState(x1));
self.stack.push(StringState(x0)); self.stack.push(StringState(x0));
Some(Ok(EnumStart("Animal", "Frog", 2))) Some(Ok(de::EnumStart("Animal", "Frog", 2)))
} }
Some(IntState(x)) => { Some(IntState(x)) => {
Some(Ok(Int(x))) Some(Ok(de::Int(x)))
} }
Some(StringState(x)) => { Some(StringState(x)) => {
Some(Ok(String(x))) Some(Ok(de::String(x)))
} }
Some(EndState) => { Some(EndState) => {
Some(Ok(End)) Some(Ok(de::End))
} }
None => None, None => None,
} }
} }
} }
impl Deserializer<Error> for AnimalDeserializer { impl de::Deserializer<Error> for AnimalDeserializer {
#[inline] #[inline]
fn end_of_stream_error<T>(&self) -> Result<T, Error> { fn end_of_stream_error<T>(&self) -> Result<T, Error> {
Err(EndOfStream) Err(EndOfStream)
} }
#[inline] #[inline]
fn syntax_error<T>(&self) -> Result<T, Error> { fn syntax_error<T>(&self, _token: de::Token) -> Result<T, Error> {
Err(SyntaxError)
}
#[inline]
fn missing_field_error<T>(&self, _field: &'static str) -> Result<T, Error> {
Err(SyntaxError) Err(SyntaxError)
} }
} }
+6 -1
View File
@@ -232,7 +232,12 @@ mod deserializer {
} }
#[inline] #[inline]
fn syntax_error<T>(&self) -> Result<T, Error> { fn syntax_error<T>(&self, _token: de::Token) -> Result<T, Error> {
Err(SyntaxError)
}
#[inline]
fn missing_field_error<T>(&self, _field: &'static str) -> Result<T, Error> {
Err(SyntaxError) Err(SyntaxError)
} }
} }
+22 -18
View File
@@ -256,8 +256,7 @@ mod decoder {
mod deserializer { mod deserializer {
use std::collections::HashMap; use std::collections::HashMap;
use super::{Outer, Inner, Error, EndOfStream, SyntaxError}; use super::{Outer, Inner, Error, EndOfStream, SyntaxError};
use de::Deserializer; use de;
use de::{Token, Uint, Char, String, Null, TupleStart, StructStart, Str, SeqStart, MapStart, End, Option};
enum State { enum State {
OuterState(Outer), OuterState(Outer),
@@ -288,15 +287,15 @@ mod deserializer {
} }
} }
impl Iterator<Result<Token, Error>> for OuterDeserializer { impl Iterator<Result<de::Token, Error>> for OuterDeserializer {
#[inline] #[inline]
fn next(&mut self) -> Option<Result<Token, Error>> { fn next(&mut self) -> Option<Result<de::Token, Error>> {
match self.stack.pop() { match self.stack.pop() {
Some(OuterState(Outer { inner })) => { Some(OuterState(Outer { inner })) => {
self.stack.push(EndState); self.stack.push(EndState);
self.stack.push(VecState(inner)); self.stack.push(VecState(inner));
self.stack.push(FieldState("inner")); self.stack.push(FieldState("inner"));
Some(Ok(StructStart("Outer", 1))) Some(Ok(de::StructStart("Outer", 1)))
} }
Some(InnerState(Inner { a: (), b, c })) => { Some(InnerState(Inner { a: (), b, c })) => {
self.stack.push(EndState); self.stack.push(EndState);
@@ -308,16 +307,16 @@ mod deserializer {
self.stack.push(NullState); self.stack.push(NullState);
self.stack.push(FieldState("a")); self.stack.push(FieldState("a"));
Some(Ok(StructStart("Inner", 3))) Some(Ok(de::StructStart("Inner", 3)))
} }
Some(FieldState(name)) => Some(Ok(Str(name))), Some(FieldState(name)) => Some(Ok(de::Str(name))),
Some(VecState(value)) => { Some(VecState(value)) => {
self.stack.push(EndState); self.stack.push(EndState);
let len = value.len(); let len = value.len();
for inner in value.move_iter().rev() { for inner in value.move_iter().rev() {
self.stack.push(InnerState(inner)); self.stack.push(InnerState(inner));
} }
Some(Ok(SeqStart(len))) Some(Ok(de::SeqStart(len)))
} }
Some(MapState(value)) => { Some(MapState(value)) => {
self.stack.push(EndState); self.stack.push(EndState);
@@ -334,30 +333,35 @@ mod deserializer {
} }
self.stack.push(StringState(key)); self.stack.push(StringState(key));
} }
Some(Ok(MapStart(len))) Some(Ok(de::MapStart(len)))
} }
Some(TupleState(len)) => Some(Ok(TupleStart(len))), Some(TupleState(len)) => Some(Ok(de::TupleStart(len))),
Some(NullState) => Some(Ok(Null)), Some(NullState) => Some(Ok(de::Null)),
Some(UintState(x)) => Some(Ok(Uint(x))), Some(UintState(x)) => Some(Ok(de::Uint(x))),
Some(CharState(x)) => Some(Ok(Char(x))), Some(CharState(x)) => Some(Ok(de::Char(x))),
Some(StringState(x)) => Some(Ok(String(x))), Some(StringState(x)) => Some(Ok(de::String(x))),
Some(OptionState(x)) => Some(Ok(Option(x))), Some(OptionState(x)) => Some(Ok(de::Option(x))),
Some(EndState) => { Some(EndState) => {
Some(Ok(End)) Some(Ok(de::End))
} }
None => None, None => None,
} }
} }
} }
impl Deserializer<Error> for OuterDeserializer { impl de::Deserializer<Error> for OuterDeserializer {
#[inline] #[inline]
fn end_of_stream_error<T>(&self) -> Result<T, Error> { fn end_of_stream_error<T>(&self) -> Result<T, Error> {
Err(EndOfStream) Err(EndOfStream)
} }
#[inline] #[inline]
fn syntax_error<T>(&self) -> Result<T, Error> { fn syntax_error<T>(&self, _token: de::Token) -> Result<T, Error> {
Err(SyntaxError)
}
#[inline]
fn missing_field_error<T>(&self, _field: &'static str) -> Result<T, Error> {
Err(SyntaxError) Err(SyntaxError)
} }
} }
+12 -2
View File
@@ -300,7 +300,12 @@ mod deserializer {
} }
#[inline] #[inline]
fn syntax_error<T>(&self) -> Result<T, Error> { fn syntax_error<T>(&self, _token: de::Token) -> Result<T, Error> {
Err(SyntaxError)
}
#[inline]
fn missing_field_error<T>(&self, _field: &'static str) -> Result<T, Error> {
Err(SyntaxError) Err(SyntaxError)
} }
} }
@@ -355,7 +360,12 @@ mod deserializer {
} }
#[inline] #[inline]
fn syntax_error<T>(&self) -> Result<T, Error> { fn syntax_error<T>(&self, _token: de::Token) -> Result<T, Error> {
Err(SyntaxError)
}
#[inline]
fn missing_field_error<T>(&self, _field: &'static str) -> Result<T, Error> {
Err(SyntaxError) Err(SyntaxError)
} }
} }
+64 -54
View File
@@ -54,7 +54,9 @@ macro_rules! to_result {
pub trait Deserializer<E>: Iterator<Result<Token, E>> { pub trait Deserializer<E>: Iterator<Result<Token, E>> {
fn end_of_stream_error<T>(&self) -> Result<T, E>; fn end_of_stream_error<T>(&self) -> Result<T, E>;
fn syntax_error<T>(&self) -> Result<T, E>; fn syntax_error<T>(&self, token: Token) -> Result<T, E>;
fn missing_field_error<T>(&self, field: &'static str) -> Result<T, E>;
#[inline] #[inline]
fn expect_token(&mut self) -> Result<Token, E> { fn expect_token(&mut self) -> Result<Token, E> {
@@ -72,10 +74,10 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
TupleStart(_) => { TupleStart(_) => {
match try!(self.expect_token()) { match try!(self.expect_token()) {
End => Ok(()), End => Ok(()),
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
@@ -83,42 +85,45 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
fn expect_bool(&mut self, token: Token) -> Result<bool, E> { fn expect_bool(&mut self, token: Token) -> Result<bool, E> {
match token { match token {
Bool(value) => Ok(value), Bool(value) => Ok(value),
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
#[inline] #[inline]
fn expect_num<T: NumCast>(&mut self, token: Token) -> Result<T, E> { fn expect_num<T: NumCast>(&mut self, token: Token) -> Result<T, E> {
match token { match token {
Int(x) => to_result!(num::cast(x), self.syntax_error()), Int(x) => to_result!(num::cast(x), self.syntax_error(Int(x))),
I8(x) => to_result!(num::cast(x), self.syntax_error()), I8(x) => to_result!(num::cast(x), self.syntax_error(I8(x))),
I16(x) => to_result!(num::cast(x), self.syntax_error()), I16(x) => to_result!(num::cast(x), self.syntax_error(I16(x))),
I32(x) => to_result!(num::cast(x), self.syntax_error()), I32(x) => to_result!(num::cast(x), self.syntax_error(I32(x))),
I64(x) => to_result!(num::cast(x), self.syntax_error()), I64(x) => to_result!(num::cast(x), self.syntax_error(I64(x))),
Uint(x) => to_result!(num::cast(x), self.syntax_error()), Uint(x) => to_result!(num::cast(x), self.syntax_error(Uint(x))),
U8(x) => to_result!(num::cast(x), self.syntax_error()), U8(x) => to_result!(num::cast(x), self.syntax_error(U8(x))),
U16(x) => to_result!(num::cast(x), self.syntax_error()), U16(x) => to_result!(num::cast(x), self.syntax_error(U16(x))),
U32(x) => to_result!(num::cast(x), self.syntax_error()), U32(x) => to_result!(num::cast(x), self.syntax_error(U32(x))),
U64(x) => to_result!(num::cast(x), self.syntax_error()), U64(x) => to_result!(num::cast(x), self.syntax_error(U64(x))),
F32(x) => to_result!(num::cast(x), self.syntax_error()), F32(x) => to_result!(num::cast(x), self.syntax_error(F32(x))),
F64(x) => to_result!(num::cast(x), self.syntax_error()), F64(x) => to_result!(num::cast(x), self.syntax_error(F64(x))),
token => self.syntax_error(token),
}
}
#[inline] #[inline]
fn expect_from_primitive<T: FromPrimitive>(&mut self, token: Token) -> Result<T, E> { fn expect_from_primitive<T: FromPrimitive>(&mut self, token: Token) -> Result<T, E> {
match token { match token {
Int(x) => to_result!(num::from_int(x), self.syntax_error()), Int(x) => to_result!(num::from_int(x), self.syntax_error(Int(x))),
I8(x) => to_result!(num::from_i8(x), self.syntax_error()), I8(x) => to_result!(num::from_i8(x), self.syntax_error(I8(x))),
I16(x) => to_result!(num::from_i16(x), self.syntax_error()), I16(x) => to_result!(num::from_i16(x), self.syntax_error(I16(x))),
I32(x) => to_result!(num::from_i32(x), self.syntax_error()), I32(x) => to_result!(num::from_i32(x), self.syntax_error(I32(x))),
I64(x) => to_result!(num::from_i64(x), self.syntax_error()), I64(x) => to_result!(num::from_i64(x), self.syntax_error(I64(x))),
Uint(x) => to_result!(num::from_uint(x), self.syntax_error()), Uint(x) => to_result!(num::from_uint(x), self.syntax_error(Uint(x))),
U8(x) => to_result!(num::from_u8(x), self.syntax_error()), U8(x) => to_result!(num::from_u8(x), self.syntax_error(U8(x))),
U16(x) => to_result!(num::from_u16(x), self.syntax_error()), U16(x) => to_result!(num::from_u16(x), self.syntax_error(U16(x))),
U32(x) => to_result!(num::from_u32(x), self.syntax_error()), U32(x) => to_result!(num::from_u32(x), self.syntax_error(U32(x))),
U64(x) => to_result!(num::from_u64(x), self.syntax_error()), U64(x) => to_result!(num::from_u64(x), self.syntax_error(U64(x))),
F32(x) => to_result!(num::from_f32(x), self.syntax_error()), F32(x) => to_result!(num::from_f32(x), self.syntax_error(F32(x))),
F64(x) => to_result!(num::from_f64(x), self.syntax_error()), F64(x) => to_result!(num::from_f64(x), self.syntax_error(F64(x))),
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
@@ -126,7 +131,7 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
fn expect_char(&mut self, token: Token) -> Result<char, E> { fn expect_char(&mut self, token: Token) -> Result<char, E> {
match token { match token {
Char(value) => Ok(value), Char(value) => Ok(value),
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
@@ -134,7 +139,7 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
fn expect_str(&mut self, token: Token) -> Result<&'static str, E> { fn expect_str(&mut self, token: Token) -> Result<&'static str, E> {
match token { match token {
Str(value) => Ok(value), Str(value) => Ok(value),
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
@@ -143,7 +148,7 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
match token { match token {
Str(value) => Ok(value.to_string()), Str(value) => Ok(value.to_string()),
String(value) => Ok(value), String(value) => Ok(value),
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
@@ -157,7 +162,7 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
let value: T = try!(Deserializable::deserialize(self)); let value: T = try!(Deserializable::deserialize(self));
Ok(Some(value)) Ok(Some(value))
} }
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
@@ -165,12 +170,12 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
fn expect_tuple_start(&mut self, token: Token) -> Result<uint, E> { fn expect_tuple_start(&mut self, token: Token) -> Result<uint, E> {
match token { match token {
TupleStart(len) => Ok(len), TupleStart(len) => Ok(len),
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
#[inline] #[inline]
fn expect_tuple_sep< fn expect_tuple_elt<
T: Deserializable T: Deserializable
>(&mut self) -> Result<T, E> { >(&mut self) -> Result<T, E> {
Deserializable::deserialize(self) Deserializable::deserialize(self)
@@ -180,7 +185,7 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
fn expect_tuple_end(&mut self) -> Result<(), E> { fn expect_tuple_end(&mut self) -> Result<(), E> {
match try!(self.expect_token()) { match try!(self.expect_token()) {
End => Ok(()), End => Ok(()),
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
@@ -191,10 +196,10 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
if name == n { if name == n {
Ok(()) Ok(())
} else { } else {
self.syntax_error() self.syntax_error(token)
} }
} }
_ => self.syntax_error(), _ => self.syntax_error(token),
} }
} }
@@ -205,15 +210,15 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
match try!(self.expect_token()) { match try!(self.expect_token()) {
Str(n) => { Str(n) => {
if name != n { if name != n {
return self.syntax_error(); return self.syntax_error(Str(n));
} }
} }
String(n) => { String(n) => {
if name != n.as_slice() { if name != n.as_slice() {
return self.syntax_error(); return self.syntax_error(String(n));
} }
} }
_ => { return self.syntax_error(); } token => { return self.syntax_error(token); }
} }
Deserializable::deserialize(self) Deserializable::deserialize(self)
@@ -223,7 +228,7 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
fn expect_struct_end(&mut self) -> Result<(), E> { fn expect_struct_end(&mut self) -> Result<(), E> {
match try!(self.expect_token()) { match try!(self.expect_token()) {
End => Ok(()), End => Ok(()),
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
@@ -234,13 +239,13 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
if name == n { if name == n {
match variants.iter().position(|variant| *variant == v) { match variants.iter().position(|variant| *variant == v) {
Some(position) => Ok(position), Some(position) => Ok(position),
None => self.syntax_error(), None => self.syntax_error(token),
} }
} else { } else {
self.syntax_error() self.syntax_error(token)
} }
} }
_ => self.syntax_error(), _ => self.syntax_error(token),
} }
} }
@@ -255,7 +260,7 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
fn expect_enum_end(&mut self) -> Result<(), E> { fn expect_enum_end(&mut self) -> Result<(), E> {
match try!(self.expect_token()) { match try!(self.expect_token()) {
End => Ok(()), End => Ok(()),
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
@@ -264,7 +269,7 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
match token { match token {
TupleStart(len) => Ok(len), TupleStart(len) => Ok(len),
SeqStart(len) => Ok(len), SeqStart(len) => Ok(len),
_ => self.syntax_error(), token => self.syntax_error(token),
} }
} }
@@ -307,7 +312,7 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
fn expect_map_start(&mut self, token: Token) -> Result<uint, E> { fn expect_map_start(&mut self, token: Token) -> Result<uint, E> {
match token { match token {
MapStart(len) => Ok(len), MapStart(len) => Ok(len),
_ => self.syntax_error(), _ => self.syntax_error(token),
} }
} }
@@ -567,7 +572,7 @@ macro_rules! impl_deserialize_tuple {
try!(d.expect_tuple_start(token)); try!(d.expect_tuple_start(token));
let result = ($({ let result = ($({
let $name = try!(Deserializable::deserialize(d)); let $name = try!(d.expect_tuple_elt());
$name $name
},)*); },)*);
@@ -617,7 +622,7 @@ impl Deserializable for IgnoreTokens {
Str(_) | String(_) => { Str(_) | String(_) => {
let _: IgnoreTokens = try!(Deserializable::deserialize(d)); let _: IgnoreTokens = try!(Deserializable::deserialize(d));
} }
_token => { return d.syntax_error(); } _token => { return d.syntax_error(token); }
} }
} }
} }
@@ -656,7 +661,7 @@ impl Deserializable for IgnoreTokens {
} }
} }
End => d.syntax_error(), End => d.syntax_error(token),
_ => Ok(IgnoreTokens), _ => Ok(IgnoreTokens),
} }
@@ -716,7 +721,7 @@ impl GatherTokens {
self.gather_map(d) self.gather_map(d)
} }
End => { End => {
d.syntax_error() d.syntax_error(token)
} }
token => { token => {
self.tokens.push(token); self.tokens.push(token);
@@ -752,7 +757,7 @@ impl GatherTokens {
self.tokens.push(token); self.tokens.push(token);
try!(self.gather(d)) try!(self.gather(d))
} }
_token => { return d.syntax_error(); } token => { return d.syntax_error(token); }
} }
} }
} }
@@ -908,6 +913,7 @@ mod tests {
enum Error { enum Error {
EndOfStream, EndOfStream,
SyntaxError, SyntaxError,
IncompleteValue,
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@@ -940,9 +946,13 @@ mod tests {
Err(EndOfStream) Err(EndOfStream)
} }
fn syntax_error<T>(&self) -> Result<T, Error> { fn syntax_error<T>(&self, _token: Token) -> Result<T, Error> {
Err(SyntaxError) Err(SyntaxError)
} }
fn missing_field_error<T>(&self, _field: &'static str) -> Result<T, Error> {
Err(IncompleteValue)
}
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
+32 -29
View File
@@ -526,7 +526,7 @@ impl de::Deserializable for Json {
object.insert(name.to_string(), List(fields)); object.insert(name.to_string(), List(fields));
Ok(Object(object)) Ok(Object(object))
} }
de::End => d.syntax_error(), de::End => d.syntax_error(de::End),
} }
} }
} }
@@ -615,10 +615,14 @@ impl de::Deserializer<ParserError> for JsonDeserializer {
Err(SyntaxError(EOFWhileParsingValue, 0, 0)) Err(SyntaxError(EOFWhileParsingValue, 0, 0))
} }
fn syntax_error<T>(&self) -> Result<T, ParserError> { fn syntax_error<T>(&self, _token: de::Token) -> Result<T, ParserError> {
Err(SyntaxError(InvalidSyntax, 0, 0)) Err(SyntaxError(InvalidSyntax, 0, 0))
} }
fn missing_field_error<T>(&self, field: &'static str) -> Result<T, ParserError> {
Err(SyntaxError(MissingField(field), 0, 0))
}
// Special case treating options as a nullable value. // Special case treating options as a nullable value.
#[inline] #[inline]
fn expect_option< fn expect_option<
@@ -702,7 +706,7 @@ pub enum ErrorCode {
InvalidUnicodeCodePoint, InvalidUnicodeCodePoint,
KeyMustBeAString, KeyMustBeAString,
LoneLeadingSurrogateInHexEscape, LoneLeadingSurrogateInHexEscape,
MissingField, MissingField(&'static str),
NotFourDigit, NotFourDigit,
NotUtf8, NotUtf8,
TrailingCharacters, TrailingCharacters,
@@ -734,33 +738,28 @@ pub enum DecoderError {
} }
*/ */
/// Returns a readable error string for a given error code.
pub fn error_str(error: ErrorCode) -> &'static str {
return match error {
EOFWhileParsingList => "EOF While parsing list",
EOFWhileParsingObject => "EOF While parsing object",
EOFWhileParsingString => "EOF While parsing string",
EOFWhileParsingValue => "EOF While parsing value",
ExpectedColon => "expected `:`",
InvalidEscape => "invalid escape",
InvalidNumber => "invalid number",
InvalidSyntax => "invalid syntax",
InvalidUnicodeCodePoint => "invalid unicode code point",
KeyMustBeAString => "key must be a string",
LoneLeadingSurrogateInHexEscape => "lone leading surrogate in hex escape",
MissingField => "missing variant",
NotFourDigit => "invalid \\u escape (not four digits)",
NotUtf8 => "contents not utf-8",
TrailingCharacters => "trailing characters",
UnexpectedEndOfHexEscape => "unexpected end of hex escape",
UnknownVariant => "unknown variant",
UnrecognizedHex => "invalid \\u escape (unrecognized hex)",
}
}
impl fmt::Show for ErrorCode { impl fmt::Show for ErrorCode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
error_str(*self).fmt(f) match *self {
EOFWhileParsingList => "EOF While parsing list".fmt(f),
EOFWhileParsingObject => "EOF While parsing object".fmt(f),
EOFWhileParsingString => "EOF While parsing string".fmt(f),
EOFWhileParsingValue => "EOF While parsing value".fmt(f),
ExpectedColon => "expected `:`".fmt(f),
InvalidEscape => "invalid escape".fmt(f),
InvalidNumber => "invalid number".fmt(f),
InvalidSyntax => "invalid syntax".fmt(f),
InvalidUnicodeCodePoint => "invalid unicode code point".fmt(f),
KeyMustBeAString => "key must be a string".fmt(f),
LoneLeadingSurrogateInHexEscape => "lone leading surrogate in hex escape".fmt(f),
MissingField(field) => write!(f, "missing field \"{}\"", field),
NotFourDigit => "invalid \\u escape (not four digits)".fmt(f),
NotUtf8 => "contents not utf-8".fmt(f),
TrailingCharacters => "trailing characters".fmt(f),
UnexpectedEndOfHexEscape => "unexpected end of hex escape".fmt(f),
UnknownVariant => "unknown variant".fmt(f),
UnrecognizedHex => "invalid \\u escape (unrecognized hex)".fmt(f),
}
} }
} }
@@ -1982,10 +1981,14 @@ impl<T: Iterator<char>> de::Deserializer<ParserError> for Parser<T> {
Err(SyntaxError(EOFWhileParsingValue, self.line, self.col)) Err(SyntaxError(EOFWhileParsingValue, self.line, self.col))
} }
fn syntax_error<U>(&self) -> Result<U, ParserError> { fn syntax_error<U>(&self, _token: de::Token) -> Result<U, ParserError> {
Err(SyntaxError(InvalidSyntax, self.line, self.col)) Err(SyntaxError(InvalidSyntax, self.line, self.col))
} }
fn missing_field_error<T>(&self, field: &'static str) -> Result<T, ParserError> {
Err(SyntaxError(MissingField(field), self.line, self.col))
}
// Special case treating options as a nullable value. // Special case treating options as a nullable value.
#[inline] #[inline]
fn expect_option< fn expect_option<