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