@@ -66,6 +66,12 @@ pub fn normalize_attribute_types(attributes: &mut Annotated<Attributes>) {
6666 ( Annotated ( Some ( Double ) , _) , Annotated ( Some ( Value :: U64 ( _) ) , _) ) => ( ) ,
6767 ( Annotated ( Some ( Double ) , _) , Annotated ( Some ( Value :: F64 ( _) ) , _) ) => ( ) ,
6868 ( Annotated ( Some ( String ) , _) , Annotated ( Some ( Value :: String ( _) ) , _) ) => ( ) ,
69+ ( Annotated ( Some ( Array ) , _) , Annotated ( Some ( Value :: Array ( arr) ) , _) ) => {
70+ if !is_supported_array ( arr) {
71+ let _ = attribute. value_mut ( ) . take ( ) ;
72+ attribute. meta_mut ( ) . add_error ( ErrorKind :: InvalidData ) ;
73+ }
74+ }
6975 // Note: currently the mapping to Kafka requires that invalid or unknown combinations
7076 // of types and values are removed from the mapping.
7177 //
@@ -90,6 +96,43 @@ pub fn normalize_attribute_types(attributes: &mut Annotated<Attributes>) {
9096 }
9197}
9298
99+ /// Returns `true` if the passed array is an array we currently support.
100+ ///
101+ /// Currently all arrays must be homogeneous types.
102+ fn is_supported_array ( arr : & [ Annotated < Value > ] ) -> bool {
103+ let mut iter = arr. iter ( ) ;
104+
105+ let Some ( first) = iter. next ( ) else {
106+ // Empty arrays are supported.
107+ return true ;
108+ } ;
109+
110+ let item = iter. try_fold ( first, |prev, current| {
111+ let r = match ( prev. value ( ) , current. value ( ) ) {
112+ ( None , None ) => prev,
113+ ( None , Some ( _) ) => current,
114+ ( Some ( _) , None ) => prev,
115+ ( Some ( Value :: String ( _) ) , Some ( Value :: String ( _) ) ) => prev,
116+ ( Some ( Value :: Bool ( _) ) , Some ( Value :: Bool ( _) ) ) => prev,
117+ (
118+ Some ( Value :: I64 ( _) | Value :: U64 ( _) | Value :: F64 ( _) ) ,
119+ Some ( Value :: I64 ( _) | Value :: U64 ( _) | Value :: F64 ( _) ) ,
120+ ) => prev,
121+ // Everything else is unsupported.
122+ //
123+ // This includes nested arrays, nested objects and mixed arrays for now.
124+ ( Some ( _) , Some ( _) ) => return None ,
125+ } ;
126+
127+ Some ( r)
128+ } ) ;
129+
130+ matches ! (
131+ item. and_then( |v| v. value( ) ) ,
132+ Some ( Value :: String ( _) | Value :: Bool ( _) | Value :: I64 ( _) | Value :: U64 ( _) | Value :: F64 ( _) )
133+ )
134+ }
135+
93136/// Adds the `received` time to the attributes.
94137pub fn normalize_received ( attributes : & mut Annotated < Attributes > , received : DateTime < Utc > ) {
95138 attributes
@@ -582,13 +625,33 @@ mod tests {
582625 },
583626 "missing_value": {
584627 "type": "string"
628+ },
629+ "supported_array_string": {
630+ "type": "array",
631+ "value": ["foo", "bar"]
632+ },
633+ "supported_array_double": {
634+ "type": "array",
635+ "value": [3, 3.0, 3]
636+ },
637+ "unsupported_array_mixed": {
638+ "type": "array",
639+ "value": ["foo", 1.0]
640+ },
641+ "unsupported_array_object": {
642+ "type": "array",
643+ "value": [{}]
644+ },
645+ "unsupported_array_in_array": {
646+ "type": "array",
647+ "value": [[]]
585648 }
586649 }"# ;
587650
588651 let mut attributes = Annotated :: < Attributes > :: from_json ( json) . unwrap ( ) ;
589652 normalize_attribute_types ( & mut attributes) ;
590653
591- insta:: assert_json_snapshot!( SerializableAnnotated ( & attributes) , @r### "
654+ insta:: assert_json_snapshot!( SerializableAnnotated ( & attributes) , @r#"
592655 {
593656 "double_with_i64": {
594657 "type": "double",
@@ -597,7 +660,25 @@ mod tests {
597660 "invalid_int_from_invalid_string": null,
598661 "missing_type": null,
599662 "missing_value": null,
663+ "supported_array_double": {
664+ "type": "array",
665+ "value": [
666+ 3,
667+ 3.0,
668+ 3
669+ ]
670+ },
671+ "supported_array_string": {
672+ "type": "array",
673+ "value": [
674+ "foo",
675+ "bar"
676+ ]
677+ },
600678 "unknown_type": null,
679+ "unsupported_array_in_array": null,
680+ "unsupported_array_mixed": null,
681+ "unsupported_array_object": null,
601682 "valid_bool": {
602683 "type": "boolean",
603684 "value": true
@@ -673,6 +754,27 @@ mod tests {
673754 }
674755 }
675756 },
757+ "unsupported_array_in_array": {
758+ "": {
759+ "err": [
760+ "invalid_data"
761+ ]
762+ }
763+ },
764+ "unsupported_array_mixed": {
765+ "": {
766+ "err": [
767+ "invalid_data"
768+ ]
769+ }
770+ },
771+ "unsupported_array_object": {
772+ "": {
773+ "err": [
774+ "invalid_data"
775+ ]
776+ }
777+ },
676778 "valid_int_from_string": {
677779 "": {
678780 "err": [
@@ -686,7 +788,7 @@ mod tests {
686788 }
687789 }
688790 }
689- "### ) ;
791+ "# ) ;
690792 }
691793
692794 #[ test]
0 commit comments