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