File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -119,9 +119,35 @@ fn gen_schema_fields(data: &Data) -> TokenStream {
119119 }
120120 } ) ;
121121 if have_schema_null {
122- if let Some ( last_ident) = type_path. path . segments . last ( ) . map ( |seg| & seg. ident ) {
123- if last_ident != "HashMap" {
124- return Error :: new (
122+ // Check if the type is HashMap or Option<HashMap>
123+ let last_segment = type_path. path . segments . last ( ) ;
124+ let is_valid = if let Some ( seg) = last_segment {
125+ let last_ident = & seg. ident ;
126+ if last_ident == "HashMap" {
127+ true
128+ } else if last_ident == "Option" {
129+ // Check if Option wraps HashMap
130+ if let PathArguments :: AngleBracketed ( args) = & seg. arguments {
131+ args. args . iter ( ) . any ( |arg| {
132+ if let syn:: GenericArgument :: Type ( Type :: Path ( inner_path) ) = arg {
133+ inner_path. path . segments . last ( ) . map ( |s| & s. ident ) == Some ( & syn:: Ident :: new ( "HashMap" , Span :: call_site ( ) ) )
134+ } else {
135+ false
136+ }
137+ } )
138+ } else {
139+ false
140+ }
141+ } else {
142+ false
143+ }
144+ } else {
145+ false
146+ } ;
147+
148+ if !is_valid {
149+ if let Some ( last_ident) = last_segment. map ( |seg| & seg. ident ) {
150+ return Error :: new (
125151 last_ident. span ( ) ,
126152 format ! ( "Can only use allow_null_container_values on HashMap fields, not {last_ident}" )
127153 ) . to_compile_error ( )
Original file line number Diff line number Diff line change @@ -721,6 +721,7 @@ pub(crate) struct Add {
721721
722722 /// Map containing metadata about this logical file.
723723 #[ cfg_attr( test, serde( skip_serializing_if = "Option::is_none" ) ) ]
724+ #[ allow_null_container_values]
724725 pub tags : Option < HashMap < String , String > > ,
725726
726727 /// Information about deletion vector (DV) associated with this add action
@@ -1075,7 +1076,7 @@ mod tests {
10751076 StructField :: nullable ( "stats" , DataType :: STRING ) ,
10761077 StructField :: nullable (
10771078 "tags" ,
1078- MapType :: new ( DataType :: STRING , DataType :: STRING , false ) ,
1079+ MapType :: new ( DataType :: STRING , DataType :: STRING , true ) ,
10791080 ) ,
10801081 deletion_vector_field ( ) ,
10811082 StructField :: nullable ( "baseRowId" , DataType :: LONG ) ,
Original file line number Diff line number Diff line change @@ -116,3 +116,10 @@ impl<T: ToNullableContainerType> GetNullableContainerStructField for T {
116116 StructField :: not_null ( name, T :: to_nullable_container_type ( ) )
117117 }
118118}
119+
120+ // Blanket impl for optional container types with nullable values
121+ impl < T : ToNullableContainerType > GetNullableContainerStructField for Option < T > {
122+ fn get_nullable_container_struct_field ( name : impl Into < String > ) -> StructField {
123+ StructField :: nullable ( name, T :: to_nullable_container_type ( ) )
124+ }
125+ }
You can’t perform that action at this time.
0 commit comments