Skip to content

Instantly share code, notes, and snippets.

@kognise
Created July 8, 2025 20:26
Show Gist options
  • Save kognise/860d2d33c2d570ec747d0de74c0f6ca0 to your computer and use it in GitHub Desktop.
Save kognise/860d2d33c2d570ec747d0de74c0f6ca0 to your computer and use it in GitHub Desktop.
#[macro_export]
macro_rules! autoparse_struct {
(
$(#[$meta:meta])*
$vis:vis $Name:ident {
$($inner:tt)*
}
) => {
autoparse_struct!(@ (reader, [$($meta)*], $vis, $Name): {$($inner)*} -> [], [], []);
};
(@ ($reader:ident, [$($meta:meta)*], $vis:vis, $Name:ident): {} -> [$($def:tt)*], [$($parse:tt)*], [$($fields:tt)*]) => {
$(#[$meta])*
#[derive(Debug)]
$vis struct $Name {
$($def)*
}
impl $crate::arinc424::utils::parseable::Parseable for $Name {
fn parse($reader: &mut $crate::arinc424::utils::string_reader::StringReader) -> Option<Self> {
$($parse)*
Some(Self {
$($fields)*
})
}
}
};
(@ ($reader:ident, $meta:tt, $vis:vis, $Name:ident): {
$field_vis:vis $field:ident: $Type:ty,
$($tail:tt)*
} -> [$($def:tt)*], [$($parse:tt)*], [$($fields:tt)*]) => {
autoparse_struct!(
@ ($reader, $meta, $vis, $Name): {$($tail)*} ->
[$($def)* $field_vis $field: $Type,],
[$($parse)* let $field = <$Type>::parse($reader)?;],
[$($fields)* $field,]
);
};
(@ ($reader:ident, $meta:tt, $vis:vis, $Name:ident): {
$Type:ty where $($pat:pat_param)|+,
$($tail:tt)*
} -> [$($def:tt)*], [$($parse:tt)*], [$($fields:tt)*]) => {
autoparse_struct!(
@ ($reader, $meta, $vis, $Name): {$($tail)*} ->
[$($def)*],
[
$($parse)*
let value = <$Type>::parse($reader)?;
if !matches!(value, $($pat)|+) {
return None;
}
],
[$($fields)*]
);
};
(@ ($reader:ident, $meta:tt, $vis:vis, $Name:ident): {
#(skip $count:expr),
$($tail:tt)*
} -> [$($def:tt)*], [$($parse:tt)*], [$($fields:tt)*]) => {
autoparse_struct!(
@ ($reader, $meta, $vis, $Name): {$($tail)*} ->
[$($def)*],
[$($parse)* $reader.skip($count);],
[$($fields)*]
);
};
(@ ($reader:ident, $meta:tt, $vis:vis, $Name:ident): {
#(continuation),
$($tail:tt)*
} -> [$($def:tt)*], [$($parse:tt)*], [$($fields:tt)*]) => {
autoparse_struct!(
@ ($reader, $meta, $vis, $Name): {$($tail)*} ->
[$($def)*],
[
$($parse)*
// Super janky but no real continuation record parsing for now.
if $reader.read(1)? != "0" {
println!("[skipping continuation record]");
return None;
}
],
[$($fields)*]
);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment