mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-13 03:11:02 +00:00
initial support for more full error messages
This commit is contained in:
+35
-9
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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<
|
||||||
|
|||||||
Reference in New Issue
Block a user