etseidl commented on code in PR #9997:
URL: https://github.com/apache/arrow-rs/pull/9997#discussion_r3283955014


##########
parquet/src/parquet_macros.rs:
##########
@@ -260,6 +260,85 @@ macro_rules! thrift_union {
     }
 }
 
+/// Macro used to generate Rust enums for Thrift unions where variants are a 
mix of unit and
+/// tuple types. This version allows for unknown variants for forwards 
compatibility.
+///
+/// Use of this macro requires modifying the thrift IDL. For variants with 
empty structs as their
+/// type, delete the typename (i.e. `1: EmptyStruct Var1;` becomes `1: Var1`). 
For variants with a
+/// non-empty type, the typename must be contained within parens (e.g. `1: 
MyType Var1;` becomes
+/// `1: (MyType) Var1;`).
+///
+/// This macro allows for specifying lifetime annotations for the resulting 
`enum` and its fields.
+///
+/// When utilizing this macro the Thrift serialization traits and structs need 
to be in scope.
+#[macro_export]
+#[allow(clippy::crate_in_macro_def)]
+macro_rules! thrift_union_with_unknown {
+    ($(#[$($def_attrs:tt)*])* union $identifier:ident $(< $lt:lifetime >)? { 
$($(#[$($field_attrs:tt)*])* $field_id:literal : $( ( $field_type:ident $(< 
$element_type:ident >)? $(< $field_lt:lifetime >)?) )? $field_name:ident 
$(;)?)* }) => {
+        $(#[cfg_attr(not(doctest), $($def_attrs)*)])*
+        #[derive(Clone, Debug, Eq, PartialEq)]
+        #[allow(non_camel_case_types)]
+        #[allow(non_snake_case)]
+        #[allow(missing_docs)]
+        pub enum $identifier $(<$lt>)? {
+            $($(#[cfg_attr(not(doctest), $($field_attrs)*)])* $field_name $( ( 
$crate::__thrift_union_type!{$field_type $($field_lt)? $($element_type)?} ) 
)?),*,
+            _Unknown {
+                /// The field id encountered when parsing the unknown variant.
+                field_id: i16,
+            },
+        }
+
+        impl<'a, R: ThriftCompactInputProtocol<'a>> ReadThrift<'a, R> for 
$identifier $(<$lt>)? {
+            fn read_thrift(prot: &mut R) -> Result<Self> {
+                let field_ident = prot.read_field_begin(0)?;
+                if field_ident.field_type == FieldType::Stop {
+                    return Err(general_err!("Received empty union from remote 
{}", stringify!($identifier)));
+                }
+                let ret = match field_ident.id {
+                    $($field_id => {
+                        let val = $crate::__thrift_read_variant!(prot, 
$field_name $($field_type $($element_type)?)?);
+                        val
+                    })*
+                    _ => {
+                        prot.skip(field_ident.field_type)?;
+                        Self::_Unknown {

Review Comment:
   Turns out it is already. Twice 😄 
   
   
https://github.com/apache/arrow-rs/blob/c46f419b4f87319637869021d46823abeb33ce1f/parquet/src/file/serialized_reader.rs#L2877
   
https://github.com/apache/arrow-rs/blob/c46f419b4f87319637869021d46823abeb33ce1f/parquet/src/arrow/arrow_reader/mod.rs#L5353
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to