@@ -804,7 +804,7 @@ impl<T : Iterator<char>> Parser<T> {
804
804
while !self . eof ( ) {
805
805
self . parse_whitespace ( ) ;
806
806
807
- if self . ch != '"' {
807
+ if self . ch != '\ "' {
808
808
return self . error ( ~"key must be a string") ;
809
809
}
810
810
@@ -866,12 +866,34 @@ pub fn Decoder(json: Json) -> Decoder {
866
866
}
867
867
}
868
868
869
+ impl Decoder {
870
+ fn err ( & self , msg : & str ) -> ! {
871
+ fail ! ( "JSON decode error: {}" , msg) ;
872
+ }
873
+ fn missing_field ( & self , field : & str , object : ~Object ) -> ! {
874
+ self . err ( format ! ( "missing required '{}' field in object: {}" ,
875
+ field, Object ( object) . to_str( ) ) )
876
+ }
877
+ fn expected ( & self , expected : & str , found : & Json ) -> ! {
878
+ let found_s = match * found {
879
+ Null => "null" ,
880
+ List ( * ) => "list" ,
881
+ Object ( * ) => "object" ,
882
+ Number ( * ) => "number" ,
883
+ String ( * ) => "string" ,
884
+ Boolean ( * ) => "boolean"
885
+ } ;
886
+ self . err ( format ! ( "expected {expct} but found {fnd}: {val}" ,
887
+ expct=expected, fnd=found_s, val=found. to_str( ) ) )
888
+ }
889
+ }
890
+
869
891
impl serialize:: Decoder for Decoder {
870
892
fn read_nil ( & mut self ) -> ( ) {
871
893
debug ! ( "read_nil" ) ;
872
894
match self . stack . pop ( ) {
873
895
Null => ( ) ,
874
- value => fail ! ( "not a null: {:?} ", value)
896
+ value => self . expected ( " null", & value)
875
897
}
876
898
}
877
899
@@ -891,33 +913,38 @@ impl serialize::Decoder for Decoder {
891
913
debug ! ( "read_bool" ) ;
892
914
match self . stack . pop ( ) {
893
915
Boolean ( b) => b,
894
- value => fail ! ( "not a boolean: {:?} ", value)
916
+ value => self . expected ( " boolean", & value)
895
917
}
896
918
}
897
919
898
920
fn read_f64 ( & mut self ) -> f64 {
899
921
debug ! ( "read_f64" ) ;
900
922
match self . stack . pop ( ) {
901
923
Number ( f) => f,
902
- value => fail ! ( "not a number: {:?} ", value)
924
+ value => self . expected ( " number", & value)
903
925
}
904
926
}
905
927
fn read_f32 ( & mut self ) -> f32 { self . read_f64 ( ) as f32 }
906
928
fn read_f32 ( & mut self ) -> f32 { self . read_f64 ( ) as f32 }
907
929
908
930
fn read_char ( & mut self ) -> char {
909
- let mut v = ~[ ] ;
910
931
let s = self . read_str ( ) ;
911
- for c in s. iter ( ) { v. push ( c) }
912
- if v. len ( ) != 1 { fail ! ( "string must have one character" ) }
913
- v[ 0 ]
932
+ {
933
+ let mut it = s. iter ( ) ;
934
+ match ( it. next ( ) , it. next ( ) ) {
935
+ // exactly one character
936
+ ( Some ( c) , None ) => return c,
937
+ _ => ( )
938
+ }
939
+ }
940
+ self . expected ( "single character string" , & String ( s) )
914
941
}
915
942
916
943
fn read_str ( & mut self ) -> ~str {
917
944
debug ! ( "read_str" ) ;
918
945
match self . stack . pop ( ) {
919
946
String ( s) => s,
920
- json => fail ! ( "not a string: {:?} ", json )
947
+ value => self . expected ( " string", & value )
921
948
}
922
949
}
923
950
@@ -933,26 +960,34 @@ impl serialize::Decoder for Decoder {
933
960
debug ! ( "read_enum_variant(names={:?})" , names) ;
934
961
let name = match self . stack . pop ( ) {
935
962
String ( s) => s,
936
- Object ( o) => {
937
- let n = match o. find ( & ~"variant") . expect ( "invalidly encoded json" ) {
938
- & String ( ref s) => s. clone ( ) ,
939
- _ => fail ! ( "invalidly encoded json" ) ,
963
+ Object ( mut o) => {
964
+ let n = match o. pop ( & ~"variant") {
965
+ Some ( String ( s) ) => s,
966
+ Some ( val) => self . expected ( "string" , & val) ,
967
+ None => self . missing_field ( "variant" , o)
940
968
} ;
941
- match o. find ( & ~"fields" ) . expect ( "invalidly encoded json ") {
942
- & List ( ref l ) => {
943
- for field in l. rev_iter ( ) {
969
+ match o. pop ( & ~"fields") {
970
+ Some ( List ( l ) ) => {
971
+ for field in l. move_rev_iter ( ) {
944
972
self . stack . push ( field. clone ( ) ) ;
945
973
}
946
974
} ,
947
- _ => fail ! ( "invalidly encoded json" )
975
+ Some ( val) => self . expected ( "list" , & val) ,
976
+ None => {
977
+ // re-insert the variant field so we're
978
+ // printing the "whole" struct in the error
979
+ // message... ick.
980
+ o. insert ( ~"variant", String ( n) ) ;
981
+ self . missing_field ( "fields" , o) ;
982
+ }
948
983
}
949
984
n
950
985
}
951
- ref json => fail ! ( "invalid variant: {:?} ", * json) ,
986
+ json => self . expected ( "string or object ", & json)
952
987
} ;
953
988
let idx = match names. iter ( ) . position ( |n| str:: eq_slice ( * n, name) ) {
954
989
Some ( idx) => idx,
955
- None => fail ! ( "Unknown variant name: {}" , name) ,
990
+ None => self . err ( format ! ( "unknown variant name: {}" , name) )
956
991
} ;
957
992
f ( self , idx)
958
993
}
@@ -999,10 +1034,9 @@ impl serialize::Decoder for Decoder {
999
1034
-> T {
1000
1035
debug ! ( "read_struct_field(name={}, idx={})" , name, idx) ;
1001
1036
match self . stack . pop ( ) {
1002
- Object ( obj) => {
1003
- let mut obj = obj;
1037
+ Object ( mut obj) => {
1004
1038
let value = match obj. pop ( & name. to_owned ( ) ) {
1005
- None => fail ! ( "no such field: {}" , name ) ,
1039
+ None => self . missing_field ( name , obj ) ,
1006
1040
Some ( json) => {
1007
1041
self . stack . push ( json) ;
1008
1042
f ( self )
@@ -1011,7 +1045,7 @@ impl serialize::Decoder for Decoder {
1011
1045
self . stack . push ( Object ( obj) ) ;
1012
1046
value
1013
1047
}
1014
- value => fail ! ( "not an object: {:?} ", value)
1048
+ value => self . expected ( " object", & value)
1015
1049
}
1016
1050
}
1017
1051
@@ -1058,7 +1092,7 @@ impl serialize::Decoder for Decoder {
1058
1092
}
1059
1093
len
1060
1094
}
1061
- _ => fail ! ( "not a list") ,
1095
+ value => self . expected ( " list", & value )
1062
1096
} ;
1063
1097
f ( self , len)
1064
1098
}
@@ -1079,7 +1113,7 @@ impl serialize::Decoder for Decoder {
1079
1113
}
1080
1114
len
1081
1115
}
1082
- json => fail ! ( "not an object: {:?} ", json ) ,
1116
+ value => self . expected ( " object", & value )
1083
1117
} ;
1084
1118
f ( self , len)
1085
1119
}
@@ -1936,4 +1970,71 @@ mod tests {
1936
1970
col: 8 u,
1937
1971
msg: @~"EOF while parsing object"}));
1938
1972
}
1973
+
1974
+ #[deriving(Decodable)]
1975
+ struct DecodeStruct {
1976
+ x: f64,
1977
+ y: bool,
1978
+ z: ~str,
1979
+ w: ~[DecodeStruct]
1980
+ }
1981
+ #[deriving(Decodable)]
1982
+ enum DecodeEnum {
1983
+ A(f64),
1984
+ B(~str)
1985
+ }
1986
+ fn check_err<T: Decodable<Decoder>>(to_parse: &'static str, expected_error: &str) {
1987
+ use std::task;
1988
+ let res = task::try(|| {
1989
+ // either fails in `decode` (which is what we want), or
1990
+ // returns Some(error_message)/None if the string was
1991
+ // invalid or valid JSON.
1992
+ match from_str(to_parse) {
1993
+ Err(e) => Some(e.to_str()),
1994
+ Ok(json) => {
1995
+ let _: T = Decodable::decode(&mut Decoder(json));
1996
+ None
1997
+ }
1998
+ }
1999
+ });
2000
+ match res {
2001
+ Ok(Some(parse_error)) => fail!(" `{ } ` is not valid json: { } ",
2002
+ to_parse, parse_error),
2003
+ Ok(None) => fail!(" `{ } ` parsed & decoded ok, expecting error `{ } `",
2004
+ to_parse, expected_error) ,
2005
+ Err ( e) => {
2006
+ let err = e. as_ref:: <~str >( ) . unwrap( ) ;
2007
+ assert!( err. contains( expected_error) ,
2008
+ "`{}` errored incorrectly, found `{}` expecting `{}`" ,
2009
+ to_parse, * err, expected_error) ;
2010
+ }
2011
+ }
2012
+ }
2013
+ #[ test]
2014
+ fn test_decode_errors_struct( ) {
2015
+ check_err:: <DecodeStruct >( "[]" , "object but found list" ) ;
2016
+ check_err:: <DecodeStruct >( "{\" x\" : true, \" y\" : true, \" z\" : \" \" , \" w\" : []}" ,
2017
+ "number but found boolean" ) ;
2018
+ check_err:: <DecodeStruct >( "{\" x\" : 1, \" y\" : [], \" z\" : \" \" , \" w\" : []}" ,
2019
+ "boolean but found list" ) ;
2020
+ check_err:: <DecodeStruct >( "{\" x\" : 1, \" y\" : true, \" z\" : {}, \" w\" : []}" ,
2021
+ "string but found object" ) ;
2022
+ check_err:: <DecodeStruct >( "{\" x\" : 1, \" y\" : true, \" z\" : \" \" , \" w\" : null}" ,
2023
+ "list but found null" ) ;
2024
+ check_err:: <DecodeStruct >( "{\" x\" : 1, \" y\" : true, \" z\" : \" \" }" ,
2025
+ "'w' field in object" ) ;
2026
+ }
2027
+ #[ test]
2028
+ fn test_decode_errors_enum( ) {
2029
+ check_err:: <DecodeEnum >( "{}" ,
2030
+ "'variant' field in object" ) ;
2031
+ check_err:: <DecodeEnum >( "{\" variant\" : 1}" ,
2032
+ "string but found number" ) ;
2033
+ check_err:: <DecodeEnum >( "{\" variant\" : \" A\" }" ,
2034
+ "'fields' field in object" ) ;
2035
+ check_err:: <DecodeEnum >( "{\" variant\" : \" A\" , \" fields\" : null}" ,
2036
+ "list but found null" ) ;
2037
+ check_err:: <DecodeEnum >( "{\" variant\" : \" C\" , \" fields\" : []}" ,
2038
+ "unknown variant name" ) ;
2039
+ }
1939
2040
}
0 commit comments