@@ -50,6 +50,20 @@ impl std::error::Error for Error {
50
50
}
51
51
}
52
52
53
+ impl Error {
54
+ fn from_validator ( jv : & JSONValidator , reason : String ) -> Self {
55
+ Error :: Validation ( vec ! [ ValidationError {
56
+ cddl_location: jv. cddl_location. clone( ) ,
57
+ json_location: jv. json_location. clone( ) ,
58
+ reason,
59
+ is_multi_type_choice: jv. is_multi_type_choice,
60
+ is_group_to_choice_enum: jv. is_group_to_choice_enum,
61
+ type_group_name_entry: jv. type_group_name_entry. map( |e| e. to_string( ) ) ,
62
+ is_multi_group_choice: jv. is_multi_group_choice,
63
+ } ] )
64
+ }
65
+ }
66
+
53
67
/// JSON validation error
54
68
#[ derive( Clone , Debug ) ]
55
69
pub struct ValidationError {
@@ -107,20 +121,6 @@ impl std::error::Error for ValidationError {
107
121
}
108
122
}
109
123
110
- impl ValidationError {
111
- fn from_validator ( jv : & JSONValidator , reason : String ) -> Self {
112
- ValidationError {
113
- cddl_location : jv. cddl_location . clone ( ) ,
114
- json_location : jv. json_location . clone ( ) ,
115
- reason,
116
- is_multi_type_choice : jv. is_multi_type_choice ,
117
- is_group_to_choice_enum : jv. is_group_to_choice_enum ,
118
- type_group_name_entry : jv. type_group_name_entry . map ( |e| e. to_string ( ) ) ,
119
- is_multi_group_choice : jv. is_multi_group_choice ,
120
- }
121
- }
122
- }
123
-
124
124
/// JSON validator type
125
125
#[ derive( Clone ) ]
126
126
pub struct JSONValidator < ' a > {
@@ -212,16 +212,16 @@ impl<'a> JSONValidator<'a> {
212
212
array_errors : None ,
213
213
}
214
214
}
215
+ }
215
216
217
+ impl < ' a > Validator < ' a , Error > for JSONValidator < ' a > {
216
218
/// Validate
217
- pub fn validate ( & mut self ) -> std:: result:: Result < ( ) , Error > {
219
+ fn validate ( & mut self ) -> std:: result:: Result < ( ) , Error > {
218
220
for r in self . cddl . rules . iter ( ) {
219
221
// First type rule is root
220
222
if let Rule :: Type { rule, .. } = r {
221
223
if rule. generic_params . is_none ( ) {
222
- self
223
- . visit_type_rule ( rule)
224
- . map_err ( |e| Error :: Validation ( vec ! [ e] ) ) ?;
224
+ self . visit_type_rule ( rule) ?;
225
225
break ;
226
226
}
227
227
}
@@ -247,8 +247,8 @@ impl<'a> JSONValidator<'a> {
247
247
}
248
248
}
249
249
250
- impl < ' a > Visitor < ' a , ValidationError > for JSONValidator < ' a > {
251
- fn visit_type_rule ( & mut self , tr : & TypeRule < ' a > ) -> visitor:: Result < ValidationError > {
250
+ impl < ' a > Visitor < ' a , Error > for JSONValidator < ' a > {
251
+ fn visit_type_rule ( & mut self , tr : & TypeRule < ' a > ) -> visitor:: Result < Error > {
252
252
if let Some ( gp) = & tr. generic_params {
253
253
if let Some ( gr) = self
254
254
. generic_rules
@@ -282,7 +282,7 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
282
282
Ok ( ( ) )
283
283
}
284
284
285
- fn visit_group_rule ( & mut self , gr : & GroupRule < ' a > ) -> visitor:: Result < ValidationError > {
285
+ fn visit_group_rule ( & mut self , gr : & GroupRule < ' a > ) -> visitor:: Result < Error > {
286
286
if let Some ( gp) = & gr. generic_params {
287
287
if let Some ( gr) = self
288
288
. generic_rules
@@ -316,7 +316,7 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
316
316
Ok ( ( ) )
317
317
}
318
318
319
- fn visit_type ( & mut self , t : & Type < ' a > ) -> visitor:: Result < ValidationError > {
319
+ fn visit_type ( & mut self , t : & Type < ' a > ) -> visitor:: Result < Error > {
320
320
if t. type_choices . len ( ) > 1 {
321
321
self . is_multi_type_choice = true ;
322
322
}
@@ -362,7 +362,7 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
362
362
Ok ( ( ) )
363
363
}
364
364
365
- fn visit_group ( & mut self , g : & Group < ' a > ) -> visitor:: Result < ValidationError > {
365
+ fn visit_group ( & mut self , g : & Group < ' a > ) -> visitor:: Result < Error > {
366
366
if g. group_choices . len ( ) > 1 {
367
367
self . is_multi_group_choice = true ;
368
368
}
@@ -439,7 +439,7 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
439
439
Ok ( ( ) )
440
440
}
441
441
442
- fn visit_group_choice ( & mut self , gc : & GroupChoice < ' a > ) -> visitor:: Result < ValidationError > {
442
+ fn visit_group_choice ( & mut self , gc : & GroupChoice < ' a > ) -> visitor:: Result < Error > {
443
443
if self . is_group_to_choice_enum {
444
444
let initial_error_count = self . errors . len ( ) ;
445
445
for tc in type_choices_from_group_choice ( self . cddl , gc) . iter ( ) {
@@ -473,7 +473,7 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
473
473
lower : & Type2 ,
474
474
upper : & Type2 ,
475
475
is_inclusive : bool ,
476
- ) -> visitor:: Result < ValidationError > {
476
+ ) -> visitor:: Result < Error > {
477
477
if let Value :: Array ( a) = & self . json {
478
478
match validate_array_occurrence (
479
479
self . occurrence . as_ref ( ) . take ( ) ,
@@ -782,7 +782,7 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
782
782
target : & Type2 < ' a > ,
783
783
ctrl : & str ,
784
784
controller : & Type2 < ' a > ,
785
- ) -> visitor:: Result < ValidationError > {
785
+ ) -> visitor:: Result < Error > {
786
786
match lookup_control_from_str ( ctrl) {
787
787
t @ Some ( Token :: EQ ) => match target {
788
788
Type2 :: Typename { ident, .. } => {
@@ -945,109 +945,29 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
945
945
}
946
946
t @ Some ( Token :: CAT ) => {
947
947
self . ctrl = t;
948
- match target {
949
- Type2 :: TextValue { value : target, .. } => match controller {
950
- Type2 :: TextValue {
951
- value : controller, ..
952
- } => {
953
- let s = format ! ( "{}{}" , target, controller) ;
954
- let mut jv = self . clone ( ) ;
955
- jv. visit_value ( & ( & * s) . into ( ) ) ?;
956
- self . errors . append ( & mut jv. errors )
957
- }
958
- Type2 :: Typename { ident, .. } => {
959
- for controller in string_literals_from_ident ( self . cddl , ident) . iter ( ) {
960
- let s = format ! ( "{}{}" , target, controller) ;
961
- let mut jv = self . clone ( ) ;
962
- jv. visit_value ( & ( & * s) . into ( ) ) ?;
963
- self . errors . append ( & mut jv. errors )
964
- }
965
- }
966
- Type2 :: UTF8ByteString {
967
- value : controller, ..
968
- } => match std:: str:: from_utf8 ( controller) {
969
- Ok ( controller) => {
970
- let s = format ! ( "{}{}" , target, controller) ;
971
- let mut jv = self . clone ( ) ;
972
- jv. visit_value ( & ( & * s) . into ( ) ) ?;
973
- self . errors . append ( & mut jv. errors )
974
- }
975
948
976
- Err ( e) => self . add_error ( format ! ( "error parsing byte string: {}" , e) ) ,
977
- } ,
978
- _ => unimplemented ! ( ) ,
979
- } ,
980
- Type2 :: Typename { ident, .. } => {
981
- // Only grab the first type choice literal from the target per
982
- // https://github.com/cbor-wg/cddl-control/issues/2#issuecomment-729253368
983
- if let Some ( target) = string_literals_from_ident ( self . cddl , ident) . first ( ) {
984
- match controller {
985
- Type2 :: TextValue {
986
- value : controller, ..
987
- } => {
988
- let s = format ! ( "{}{}" , target, controller) ;
989
- let mut jv = self . clone ( ) ;
990
- jv. visit_value ( & ( & * s) . into ( ) ) ?;
991
- self . errors . append ( & mut jv. errors )
992
- }
993
- Type2 :: Typename { ident, .. } => {
994
- for controller in string_literals_from_ident ( self . cddl , ident) . iter ( ) {
995
- let s = format ! ( "{}{}" , target, controller) ;
996
- let mut jv = self . clone ( ) ;
997
- jv. visit_value ( & ( & * s) . into ( ) ) ?;
998
- self . errors . append ( & mut jv. errors )
999
- }
1000
- }
1001
- Type2 :: UTF8ByteString {
1002
- value : controller, ..
1003
- } => match std:: str:: from_utf8 ( controller) {
1004
- Ok ( controller) => {
1005
- let s = format ! ( "{}{}" , target, controller) ;
1006
- let mut jv = self . clone ( ) ;
1007
- jv. visit_value ( & ( & * s) . into ( ) ) ?;
1008
- self . errors . append ( & mut jv. errors )
1009
- }
1010
- Err ( e) => self . add_error ( format ! ( "error parsing byte string: {}" , e) ) ,
1011
- } ,
1012
- _ => unimplemented ! ( ) ,
1013
- }
1014
- }
949
+ let mut values = Vec :: new ( ) ;
950
+ if let Err ( e) = cat_operation ( self . cddl , target, controller, & mut values) {
951
+ self . add_error ( e) ;
952
+ }
953
+
954
+ let mut success = false ;
955
+ let mut errors = Vec :: new ( ) ;
956
+ for v in values. iter ( ) {
957
+ let mut jv = self . clone ( ) ;
958
+ jv. visit_value ( & ( & * * v) . into ( ) ) ?;
959
+ if jv. errors . is_empty ( ) {
960
+ success = true ;
961
+ break ;
1015
962
}
1016
- Type2 :: UTF8ByteString { value : target, .. } => match std:: str:: from_utf8 ( target) {
1017
- Ok ( target) => match controller {
1018
- Type2 :: TextValue {
1019
- value : controller, ..
1020
- } => {
1021
- let s = format ! ( "{}{}" , target, controller) ;
1022
- let mut jv = self . clone ( ) ;
1023
- jv. visit_value ( & ( & * s) . into ( ) ) ?;
1024
- self . errors . append ( & mut jv. errors )
1025
- }
1026
- Type2 :: Typename { ident, .. } => {
1027
- for controller in string_literals_from_ident ( self . cddl , ident) . iter ( ) {
1028
- let s = format ! ( "{}{}" , target, controller) ;
1029
- let mut jv = self . clone ( ) ;
1030
- jv. visit_value ( & ( & * s) . into ( ) ) ?;
1031
- self . errors . append ( & mut jv. errors )
1032
- }
1033
- }
1034
- Type2 :: UTF8ByteString {
1035
- value : controller, ..
1036
- } => match std:: str:: from_utf8 ( controller) {
1037
- Ok ( controller) => {
1038
- let s = format ! ( "{}{}" , target, controller) ;
1039
- let mut jv = self . clone ( ) ;
1040
- jv. visit_value ( & ( & * s) . into ( ) ) ?;
1041
- self . errors . append ( & mut jv. errors )
1042
- }
1043
- Err ( e) => self . add_error ( format ! ( "error parsing byte string: {}" , e) ) ,
1044
- } ,
1045
- _ => unimplemented ! ( ) ,
1046
- } ,
1047
- Err ( e) => self . add_error ( format ! ( "error parsing byte string: {}" , e) ) ,
1048
- } ,
1049
- _ => unimplemented ! ( ) ,
963
+
964
+ errors. append ( & mut jv. errors )
1050
965
}
966
+
967
+ if !success {
968
+ self . errors . append ( & mut errors)
969
+ }
970
+
1051
971
self . ctrl = None ;
1052
972
}
1053
973
_ => {
@@ -1058,7 +978,7 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
1058
978
Ok ( ( ) )
1059
979
}
1060
980
1061
- fn visit_type2 ( & mut self , t2 : & Type2 < ' a > ) -> visitor:: Result < ValidationError > {
981
+ fn visit_type2 ( & mut self , t2 : & Type2 < ' a > ) -> visitor:: Result < Error > {
1062
982
match t2 {
1063
983
Type2 :: TextValue { value, .. } => self . visit_value ( & token:: Value :: TEXT ( value) ) ,
1064
984
Type2 :: Map { group, .. } => match & self . json {
@@ -1372,7 +1292,7 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
1372
1292
}
1373
1293
}
1374
1294
1375
- fn visit_identifier ( & mut self , ident : & Identifier < ' a > ) -> visitor:: Result < ValidationError > {
1295
+ fn visit_identifier ( & mut self , ident : & Identifier < ' a > ) -> visitor:: Result < Error > {
1376
1296
if let Some ( name) = self . eval_generic_rule {
1377
1297
if let Some ( gr) = self
1378
1298
. generic_rules
@@ -1613,7 +1533,7 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
1613
1533
fn visit_value_member_key_entry (
1614
1534
& mut self ,
1615
1535
entry : & ValueMemberKeyEntry < ' a > ,
1616
- ) -> visitor:: Result < ValidationError > {
1536
+ ) -> visitor:: Result < Error > {
1617
1537
if let Some ( occur) = & entry. occur {
1618
1538
self . visit_occurrence ( occur) ?;
1619
1539
}
@@ -1683,23 +1603,23 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
1683
1603
fn visit_type_groupname_entry (
1684
1604
& mut self ,
1685
1605
entry : & TypeGroupnameEntry < ' a > ,
1686
- ) -> visitor:: Result < ValidationError > {
1606
+ ) -> visitor:: Result < Error > {
1687
1607
self . type_group_name_entry = Some ( entry. name . ident ) ;
1688
1608
walk_type_groupname_entry ( self , entry) ?;
1689
1609
self . type_group_name_entry = None ;
1690
1610
1691
1611
Ok ( ( ) )
1692
1612
}
1693
1613
1694
- fn visit_memberkey ( & mut self , mk : & MemberKey < ' a > ) -> visitor:: Result < ValidationError > {
1614
+ fn visit_memberkey ( & mut self , mk : & MemberKey < ' a > ) -> visitor:: Result < Error > {
1695
1615
if let MemberKey :: Type1 { is_cut, .. } = mk {
1696
1616
self . is_cut_present = * is_cut;
1697
1617
}
1698
1618
1699
1619
walk_memberkey ( self , mk)
1700
1620
}
1701
1621
1702
- fn visit_value ( & mut self , value : & token:: Value < ' a > ) -> visitor:: Result < ValidationError > {
1622
+ fn visit_value ( & mut self , value : & token:: Value < ' a > ) -> visitor:: Result < Error > {
1703
1623
let error: Option < String > = match & self . json {
1704
1624
Value :: Number ( n) => match value {
1705
1625
token:: Value :: INT ( v) => match n. as_i64 ( ) {
@@ -1787,17 +1707,13 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
1787
1707
let re = regex:: Regex :: new (
1788
1708
& format_regex (
1789
1709
serde_json:: from_str :: < Value > ( & format ! ( "\" {}\" " , t) )
1790
- . map_err ( |e| ValidationError :: from_validator ( self , e . to_string ( ) ) ) ?
1710
+ . map_err ( Error :: JSONParsing ) ?
1791
1711
. as_str ( )
1792
- . ok_or_else ( || {
1793
- ValidationError :: from_validator ( self , "malformed regex" . to_string ( ) )
1794
- } ) ?,
1712
+ . ok_or_else ( || Error :: from_validator ( self , "malformed regex" . to_string ( ) ) ) ?,
1795
1713
)
1796
- . ok_or_else ( || {
1797
- ValidationError :: from_validator ( self , "malformed regex" . to_string ( ) )
1798
- } ) ?,
1714
+ . ok_or_else ( || Error :: from_validator ( self , "malformed regex" . to_string ( ) ) ) ?,
1799
1715
)
1800
- . map_err ( |e| ValidationError :: from_validator ( self , e. to_string ( ) ) ) ?;
1716
+ . map_err ( |e| Error :: from_validator ( self , e. to_string ( ) ) ) ?;
1801
1717
1802
1718
if re. is_match ( s) {
1803
1719
None
@@ -1808,6 +1724,11 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
1808
1724
_ => {
1809
1725
if s == t {
1810
1726
None
1727
+ } else if let Some ( Token :: CAT ) = & self . ctrl {
1728
+ Some ( format ! (
1729
+ "expected value to match concatenated string {}, got \" {}\" " ,
1730
+ value, s
1731
+ ) )
1811
1732
} else if let Some ( ctrl) = & self . ctrl {
1812
1733
Some ( format ! ( "expected value {} {}, got \" {}\" " , ctrl, value, s) )
1813
1734
} else {
@@ -1959,7 +1880,7 @@ impl<'a> Visitor<'a, ValidationError> for JSONValidator<'a> {
1959
1880
Ok ( ( ) )
1960
1881
}
1961
1882
1962
- fn visit_occurrence ( & mut self , o : & Occurrence ) -> visitor:: Result < ValidationError > {
1883
+ fn visit_occurrence ( & mut self , o : & Occurrence ) -> visitor:: Result < Error > {
1963
1884
self . occurrence = Some ( o. occur . clone ( ) ) ;
1964
1885
1965
1886
Ok ( ( ) )
@@ -1975,12 +1896,10 @@ mod tests {
1975
1896
fn validate ( ) -> std:: result:: Result < ( ) , Box < dyn std:: error:: Error > > {
1976
1897
let cddl = indoc ! (
1977
1898
r#"
1978
- a = "foo" .cat '
1979
- bar
1980
- baz
1981
- '"#
1899
+ a = "foo" .cat b
1900
+ b = "bar" / "baz" / "test""#
1982
1901
) ;
1983
- let json = r#""foo\n bar\n baz\n ""# ;
1902
+ let json = r#""foobar ""# ;
1984
1903
1985
1904
let mut lexer = lexer_from_str ( cddl) ;
1986
1905
let cddl = cddl_from_str ( & mut lexer, cddl, true ) . map_err ( json:: Error :: CDDLParsing ) ;
0 commit comments