1#[doc(hidden)]
25#[macro_export]
26#[expect(clippy::allow_attributes)]
27#[allow(clippy::crate_in_macro_def)]
28macro_rules! thrift_enum {
34 ($(#[$($def_attrs:tt)*])* enum $identifier:ident { $($(#[$($field_attrs:tt)*])* $field_name:ident = $field_value:literal;)* }) => {
35 $(#[$($def_attrs)*])*
36 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
37 #[allow(clippy::allow_attributes)]
38 #[allow(non_camel_case_types)]
39 #[allow(missing_docs)]
40 pub enum $identifier {
41 $($(#[cfg_attr(not(doctest), $($field_attrs)*)])* $field_name = $field_value,)*
42 }
43
44 impl<'a, R: ThriftCompactInputProtocol<'a>> ReadThrift<'a, R> for $identifier {
45 #[allow(clippy::allow_attributes)]
46 #[allow(deprecated)]
47 fn read_thrift(prot: &mut R) -> Result<Self> {
48 let val = prot.read_i32()?;
49 match val {
50 $($field_value => Ok(Self::$field_name),)*
51 _ => Err(general_err!("Unexpected {} {}", stringify!($identifier), val)),
52 }
53 }
54 }
55
56 impl fmt::Display for $identifier {
57 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
58 write!(f, "{self:?}")
59 }
60 }
61
62 impl WriteThrift for $identifier {
63 const ELEMENT_TYPE: ElementType = ElementType::I32;
64
65 fn write_thrift<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>) -> Result<()> {
66 writer.write_i32(*self as i32)
67 }
68 }
69
70 impl WriteThriftField for $identifier {
71 fn write_thrift_field<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>, field_id: i16, last_field_id: i16) -> Result<i16> {
72 writer.write_field_begin(FieldType::I32, field_id, last_field_id)?;
73 self.write_thrift(writer)?;
74 Ok(field_id)
75 }
76 }
77
78 impl $identifier {
79 #[allow(clippy::allow_attributes)]
80 #[allow(deprecated)]
81 #[doc = "Returns a slice containing every variant of this enum."]
82 #[allow(dead_code)]
83 pub const VARIANTS: &'static [Self] = &[
84 $(Self::$field_name),*
85 ];
86
87 #[allow(clippy::allow_attributes)]
88 #[allow(deprecated)]
89 const fn max_discriminant_impl() -> i32 {
90 let values: &[i32] = &[$($field_value),*];
91 let mut max = values[0];
92 let mut idx = 1;
93 while idx < values.len() {
94 let candidate = values[idx];
95 if candidate > max {
96 max = candidate;
97 }
98 idx += 1;
99 }
100 max
101 }
102
103 #[allow(clippy::allow_attributes)]
104 #[allow(deprecated)]
105 #[doc = "Returns the largest discriminant value defined for this enum."]
106 #[allow(dead_code)]
107 pub const MAX_DISCRIMINANT: i32 = Self::max_discriminant_impl();
108 }
109 }
110}
111
112#[doc(hidden)]
125#[macro_export]
126#[expect(clippy::allow_attributes)]
127#[allow(clippy::crate_in_macro_def)]
128macro_rules! thrift_union_all_empty {
129 ($(#[$($def_attrs:tt)*])* union $identifier:ident { $($(#[$($field_attrs:tt)*])* $field_id:literal : $field_type:ident $(< $element_type:ident >)? $field_name:ident $(;)?)* }) => {
130 $(#[cfg_attr(not(doctest), $($def_attrs)*)])*
131 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
132 #[allow(clippy::allow_attributes)]
133 #[allow(non_camel_case_types)]
134 #[allow(non_snake_case)]
135 #[allow(missing_docs)]
136 pub enum $identifier {
137 $($(#[cfg_attr(not(doctest), $($field_attrs)*)])* $field_name),*
138 }
139
140 impl<'a, R: ThriftCompactInputProtocol<'a>> ReadThrift<'a, R> for $identifier {
141 fn read_thrift(prot: &mut R) -> Result<Self> {
142 let field_ident = prot.read_field_begin(0)?;
143 if field_ident.field_type == FieldType::Stop {
144 return Err(general_err!("Received empty union from remote {}", stringify!($identifier)));
145 }
146 let ret = match field_ident.id {
147 $($field_id => {
148 prot.skip_empty_struct()?;
149 Self::$field_name
150 }
151 )*
152 _ => {
153 return Err(general_err!("Unexpected {} {}", stringify!($identifier), field_ident.id));
154 }
155 };
156 let field_ident = prot.read_field_begin(field_ident.id)?;
157 if field_ident.field_type != FieldType::Stop {
158 return Err(general_err!(
159 "Received multiple fields for union from remote {}", stringify!($identifier)
160 ));
161 }
162 Ok(ret)
163 }
164 }
165
166 impl WriteThrift for $identifier {
167 const ELEMENT_TYPE: ElementType = ElementType::Struct;
168
169 fn write_thrift<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>) -> Result<()> {
170 match *self {
171 $(Self::$field_name => writer.write_empty_struct($field_id, 0)?,)*
172 };
173 writer.write_struct_end()
175 }
176 }
177
178 impl WriteThriftField for $identifier {
179 fn write_thrift_field<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>, field_id: i16, last_field_id: i16) -> Result<i16> {
180 writer.write_field_begin(FieldType::Struct, field_id, last_field_id)?;
181 self.write_thrift(writer)?;
182 Ok(field_id)
183 }
184 }
185 }
186}
187
188#[doc(hidden)]
201#[macro_export]
202#[expect(clippy::allow_attributes)]
203#[allow(clippy::crate_in_macro_def)]
204macro_rules! thrift_union {
205 ($(#[$($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 $(;)?)* }) => {
206 $(#[cfg_attr(not(doctest), $($def_attrs)*)])*
207 #[derive(Clone, Debug, Eq, PartialEq)]
208 #[allow(clippy::allow_attributes)]
209 #[allow(non_camel_case_types)]
210 #[allow(non_snake_case)]
211 #[allow(missing_docs)]
212 pub enum $identifier $(<$lt>)? {
213 $($(#[cfg_attr(not(doctest), $($field_attrs)*)])* $field_name $( ( $crate::__thrift_union_type!{$field_type $($field_lt)? $($element_type)?} ) )?),*
214 }
215
216 impl<'a, R: ThriftCompactInputProtocol<'a>> ReadThrift<'a, R> for $identifier $(<$lt>)? {
217 fn read_thrift(prot: &mut R) -> Result<Self> {
218 let field_ident = prot.read_field_begin(0)?;
219 if field_ident.field_type == FieldType::Stop {
220 return Err(general_err!("Received empty union from remote {}", stringify!($identifier)));
221 }
222 let ret = match field_ident.id {
223 $($field_id => {
224 let val = $crate::__thrift_read_variant!(prot, $field_name $($field_type $($element_type)?)?);
225 val
226 })*
227 _ => {
228 return Err(general_err!("Unexpected {} {}", stringify!($identifier), field_ident.id));
229 }
230 };
231 let field_ident = prot.read_field_begin(field_ident.id)?;
232 if field_ident.field_type != FieldType::Stop {
233 return Err(general_err!(
234 concat!("Received multiple fields for union from remote {}", stringify!($identifier))
235 ));
236 }
237 Ok(ret)
238 }
239 }
240
241 impl $(<$lt>)? WriteThrift for $identifier $(<$lt>)? {
242 const ELEMENT_TYPE: ElementType = ElementType::Struct;
243
244 fn write_thrift<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>) -> Result<()> {
245 match self {
246 $($crate::__thrift_write_variant_lhs!($field_name $($field_type)?, variant_val) =>
247 $crate::__thrift_write_variant_rhs!($field_id $($field_type)?, writer, variant_val),)*
248 };
249 writer.write_struct_end()
250 }
251 }
252
253 impl $(<$lt>)? WriteThriftField for $identifier $(<$lt>)? {
254 fn write_thrift_field<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>, field_id: i16, last_field_id: i16) -> Result<i16> {
255 writer.write_field_begin(FieldType::Struct, field_id, last_field_id)?;
256 self.write_thrift(writer)?;
257 Ok(field_id)
258 }
259 }
260 }
261}
262
263#[doc(hidden)]
275#[macro_export]
276#[expect(clippy::allow_attributes)]
277#[allow(clippy::crate_in_macro_def)]
278macro_rules! thrift_union_with_unknown {
279 ($(#[$($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 $(;)?)* }) => {
280 $(#[cfg_attr(not(doctest), $($def_attrs)*)])*
281 #[derive(Clone, Debug, Eq, PartialEq)]
282 #[allow(clippy::allow_attributes)]
283 #[allow(non_camel_case_types)]
284 #[allow(non_snake_case)]
285 #[allow(missing_docs)]
286 pub enum $identifier $(<$lt>)? {
287 $($(#[cfg_attr(not(doctest), $($field_attrs)*)])* $field_name $( ( $crate::__thrift_union_type!{$field_type $($field_lt)? $($element_type)?} ) )?),*,
288 _Unknown {
289 field_id: i16,
291 },
292 }
293
294 impl<'a, R: ThriftCompactInputProtocol<'a>> ReadThrift<'a, R> for $identifier $(<$lt>)? {
295 fn read_thrift(prot: &mut R) -> Result<Self> {
296 let field_ident = prot.read_field_begin(0)?;
297 if field_ident.field_type == FieldType::Stop {
298 return Err(general_err!("Received empty union from remote {}", stringify!($identifier)));
299 }
300 let ret = match field_ident.id {
301 $($field_id => {
302 let val = $crate::__thrift_read_variant!(prot, $field_name $($field_type $($element_type)?)?);
303 val
304 })*
305 _ => {
306 prot.skip(field_ident.field_type)?;
307 Self::_Unknown {
308 field_id: field_ident.id,
309 }
310 }
311 };
312 let field_ident = prot.read_field_begin(field_ident.id)?;
313 if field_ident.field_type != FieldType::Stop {
314 return Err(general_err!(
315 concat!("Received multiple fields for union from remote {}", stringify!($identifier))
316 ));
317 }
318 Ok(ret)
319 }
320 }
321
322 impl $(<$lt>)? WriteThrift for $identifier $(<$lt>)? {
323 const ELEMENT_TYPE: ElementType = ElementType::Struct;
324
325 fn write_thrift<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>) -> Result<()> {
326 match self {
327 $($crate::__thrift_write_variant_lhs!($field_name $($field_type)?, variant_val) =>
328 $crate::__thrift_write_variant_rhs!($field_id $($field_type)?, writer, variant_val),)*
329 Self::_Unknown{..} => return Err(general_err!("Trying to write unknown variant")),
330 };
331 writer.write_struct_end()
332 }
333 }
334
335 impl $(<$lt>)? WriteThriftField for $identifier $(<$lt>)? {
336 fn write_thrift_field<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>, field_id: i16, last_field_id: i16) -> Result<i16> {
337 writer.write_field_begin(FieldType::Struct, field_id, last_field_id)?;
338 self.write_thrift(writer)?;
339 Ok(field_id)
340 }
341 }
342 }
343}
344
345#[doc(hidden)]
353#[macro_export]
354macro_rules! thrift_struct {
355 ($(#[$($def_attrs:tt)*])* $vis:vis struct $identifier:ident $(< $lt:lifetime >)? { $($(#[$($field_attrs:tt)*])* $field_id:literal : $required_or_optional:ident $field_type:ident $(< $field_lt:lifetime >)? $(< $element_type:ident >)? $field_name:ident $(= $default_value:literal)? $(;)?)* }) => {
356 $(#[cfg_attr(not(doctest), $($def_attrs)*)])*
357 #[derive(Clone, Debug, Eq, PartialEq)]
358 #[allow(clippy::allow_attributes)]
359 #[allow(non_camel_case_types)]
360 #[allow(non_snake_case)]
361 #[allow(missing_docs)]
362 $vis struct $identifier $(<$lt>)? {
363 $($(#[cfg_attr(not(doctest), $($field_attrs)*)])* $vis $field_name: $crate::__thrift_required_or_optional!($required_or_optional $crate::__thrift_field_type!($field_type $($field_lt)? $($element_type)?))),*
364 }
365
366 impl<'a, R: ThriftCompactInputProtocol<'a>> ReadThrift<'a, R> for $identifier $(<$lt>)? {
367 fn read_thrift(prot: &mut R) -> Result<Self> {
368 $(let mut $field_name: Option<$crate::__thrift_field_type!($field_type $($field_lt)? $($element_type)?)> = None;)*
369 let mut last_field_id = 0i16;
370 loop {
371 let field_ident = prot.read_field_begin(last_field_id)?;
372 if field_ident.field_type == FieldType::Stop {
373 break;
374 }
375 match field_ident.id {
376 $($field_id => {
377 let val = $crate::__thrift_read_field!(prot, field_ident, $field_type $($field_lt)? $($element_type)?);
378 $field_name = Some(val);
379 })*
380 _ => {
381 prot.skip(field_ident.field_type)?;
382 }
383 };
384 last_field_id = field_ident.id;
385 }
386 $($crate::__thrift_result_required_or_optional!($required_or_optional $field_name);)*
387 Ok(Self {
388 $($field_name),*
389 })
390 }
391 }
392
393 impl $(<$lt>)? WriteThrift for $identifier $(<$lt>)? {
394 const ELEMENT_TYPE: ElementType = ElementType::Struct;
395
396 #[allow(clippy::allow_attributes)]
397 #[allow(unused_assignments)]
398 fn write_thrift<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>) -> Result<()> {
399 #[allow(unused_mut, unused_variables)]
400 let mut last_field_id = 0i16;
401 $($crate::__thrift_write_required_or_optional_field!($required_or_optional $field_name, $field_id, $field_type, self, writer, last_field_id);)*
402 writer.write_struct_end()
403 }
404 }
405
406 impl $(<$lt>)? WriteThriftField for $identifier $(<$lt>)? {
407 fn write_thrift_field<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>, field_id: i16, last_field_id: i16) -> Result<i16> {
408 writer.write_field_begin(FieldType::Struct, field_id, last_field_id)?;
409 self.write_thrift(writer)?;
410 Ok(field_id)
411 }
412 }
413 }
414}
415
416#[doc(hidden)]
417#[macro_export]
418macro_rules! write_thrift_field {
420 ($identifier:ident $(< $lt:lifetime >)?, $fld_type:expr) => {
421 impl $(<$lt>)? WriteThriftField for $identifier $(<$lt>)? {
422 fn write_thrift_field<W: Write>(&self, writer: &mut ThriftCompactOutputProtocol<W>, field_id: i16, last_field_id: i16) -> Result<i16> {
423 writer.write_field_begin($fld_type, field_id, last_field_id)?;
424 self.write_thrift(writer)?;
425 Ok(field_id)
426 }
427 }
428 }
429}
430
431#[doc(hidden)]
432#[macro_export]
433macro_rules! __thrift_write_required_or_optional_field {
434 (required $field_name:ident, $field_id:literal, $field_type:ident, $self:tt, $writer:tt, $last_id:tt) => {
435 $crate::__thrift_write_required_field!(
436 $field_type,
437 $field_name,
438 $field_id,
439 $self,
440 $writer,
441 $last_id
442 )
443 };
444 (optional $field_name:ident, $field_id:literal, $field_type:ident, $self:tt, $writer:tt, $last_id:tt) => {
445 $crate::__thrift_write_optional_field!(
446 $field_type,
447 $field_name,
448 $field_id,
449 $self,
450 $writer,
451 $last_id
452 )
453 };
454}
455
456#[doc(hidden)]
457#[macro_export]
458macro_rules! __thrift_write_required_field {
459 (binary, $field_name:ident, $field_id:literal, $self:ident, $writer:ident, $last_id:ident) => {
460 $writer.write_field_begin(FieldType::Binary, $field_id, $last_id)?;
461 $writer.write_bytes($self.$field_name)?;
462 $last_id = $field_id;
463 };
464 ($field_type:ident, $field_name:ident, $field_id:literal, $self:ident, $writer:ident, $last_id:ident) => {
465 $last_id = $self
466 .$field_name
467 .write_thrift_field($writer, $field_id, $last_id)?;
468 };
469}
470
471#[doc(hidden)]
472#[macro_export]
473macro_rules! __thrift_write_optional_field {
474 (binary, $field_name:ident, $field_id:literal, $self:ident, $writer:tt, $last_id:tt) => {
475 if $self.$field_name.is_some() {
476 $writer.write_field_begin(FieldType::Binary, $field_id, $last_id)?;
477 $writer.write_bytes($self.$field_name.as_ref().unwrap())?;
478 $last_id = $field_id;
479 }
480 };
481 ($field_type:ident, $field_name:ident, $field_id:literal, $self:ident, $writer:tt, $last_id:tt) => {
482 if $self.$field_name.is_some() {
483 $last_id = $self
484 .$field_name
485 .as_ref()
486 .unwrap()
487 .write_thrift_field($writer, $field_id, $last_id)?;
488 }
489 };
490}
491
492#[doc(hidden)]
493#[macro_export]
494macro_rules! __thrift_required_or_optional {
495 (required $field_type:ty) => { $field_type };
496 (optional $field_type:ty) => { Option<$field_type> };
497}
498
499#[doc(hidden)]
502#[macro_export]
503macro_rules! __thrift_result_required_or_optional {
504 (required $field_name:ident) => {
505 let Some($field_name) = $field_name else {
506 return Err(general_err!(concat!(
507 "Required field ",
508 stringify!($field_name),
509 " is missing",
510 )));
511 };
512 };
513 (optional $field_name:ident) => {};
514}
515
516#[doc(hidden)]
517#[macro_export]
518macro_rules! __thrift_read_field {
519 ($prot:tt, $field_ident:tt, list $lt:lifetime binary) => {
520 read_thrift_vec::<&'a [u8], R>(&mut *$prot)?
521 };
522 ($prot:tt, $field_ident:tt, list $lt:lifetime $element_type:ident) => {
523 read_thrift_vec::<$element_type, R>(&mut *$prot)?
524 };
525 ($prot:tt, $field_ident:tt, list string) => {
526 read_thrift_vec::<String, R>(&mut *$prot)?
527 };
528 ($prot:tt, $field_ident:tt, list $element_type:ident) => {
529 read_thrift_vec::<$element_type, R>(&mut *$prot)?
530 };
531 ($prot:tt, $field_ident:tt, string $lt:lifetime) => {
532 <&$lt str>::read_thrift(&mut *$prot)?
533 };
534 ($prot:tt, $field_ident:tt, binary $lt:lifetime) => {
535 <&$lt [u8]>::read_thrift(&mut *$prot)?
536 };
537 ($prot:tt, $field_ident:tt, $field_type:ident $lt:lifetime) => {
538 $field_type::read_thrift(&mut *$prot)?
539 };
540 ($prot:tt, $field_ident:tt, string) => {
541 String::read_thrift(&mut *$prot)?
542 };
543 ($prot:tt, $field_ident:tt, binary) => {
544 $prot.read_bytes_owned()?
546 };
547 ($prot:tt, $field_ident:tt, double) => {
548 $crate::parquet_thrift::OrderedF64::read_thrift(&mut *$prot)?
549 };
550 ($prot:tt, $field_ident:tt, bool) => {
551 $field_ident.bool_val()?
552 };
553 ($prot:tt, $field_ident:tt, $field_type:ident) => {
554 $field_type::read_thrift(&mut *$prot)?
555 };
556}
557
558#[doc(hidden)]
559#[macro_export]
560macro_rules! __thrift_field_type {
561 (binary $lt:lifetime) => { &$lt [u8] };
562 (string $lt:lifetime) => { &$lt str };
563 ($field_type:ident $lt:lifetime) => { $field_type<$lt> };
564 (list $lt:lifetime $element_type:ident) => { Vec< $crate::__thrift_field_type!($element_type $lt) > };
565 (list string) => { Vec<String> };
566 (list $element_type:ident) => { Vec< $crate::__thrift_field_type!($element_type) > };
567 (binary) => { Vec<u8> };
568 (string) => { String };
569 (double) => { $crate::parquet_thrift::OrderedF64 };
570 ($field_type:ty) => { $field_type };
571}
572
573#[doc(hidden)]
574#[macro_export]
575macro_rules! __thrift_union_type {
576 (binary $lt:lifetime) => { &$lt [u8] };
577 (string $lt:lifetime) => { &$lt str };
578 ($field_type:ident $lt:lifetime) => { $field_type<$lt> };
579 ($field_type:ident) => { $field_type };
580 (list $field_type:ident) => { Vec<$field_type> };
581}
582
583#[doc(hidden)]
584#[macro_export]
585macro_rules! __thrift_read_variant {
586 ($prot:tt, $field_name:ident $field_type:ident) => {
587 Self::$field_name($field_type::read_thrift(&mut *$prot)?)
588 };
589 ($prot:tt, $field_name:ident list $field_type:ident) => {
590 Self::$field_name(Vec::<$field_type>::read_thrift(&mut *$prot)?)
591 };
592 ($prot:tt, $field_name:ident) => {{
593 $prot.skip_empty_struct()?;
594 Self::$field_name
595 }};
596}
597
598#[doc(hidden)]
599#[macro_export]
600macro_rules! __thrift_write_variant_lhs {
601 ($field_name:ident $field_type:ident, $val:tt) => {
602 Self::$field_name($val)
603 };
604 ($field_name:ident, $val:tt) => {
605 Self::$field_name
606 };
607}
608
609#[doc(hidden)]
610#[macro_export]
611macro_rules! __thrift_write_variant_rhs {
612 ($field_id:literal $field_type:ident, $writer:tt, $val:ident) => {
613 $val.write_thrift_field($writer, $field_id, 0)?
614 };
615 ($field_id:literal, $writer:tt, $val:tt) => {
616 $writer.write_empty_struct($field_id, 0)?
617 };
618}