use reth_db_api::table::Decompress; /// Generic Mask helper struct for selecting specific column values to read and decompress. /// /// #### Explanation: /// /// A `NippyJar` static file row can contain multiple column values. To specify the column values /// to be read, a mask is utilized. /// /// For example, a static file with three columns, if the first and last columns are queried, the /// mask `0b101` would be passed. To select only the second column, the mask `0b010` would be used. /// /// Since each static file has its own column distribution, different wrapper types are necessary. /// For instance, `B256` might be the third column in the `Header` segment, while being the second /// column in another segment. Hence, `Mask` would only be applicable to one of these /// scenarios. /// /// Alongside, the column selector traits (eg. [`ColumnSelectorOne`]) this provides a structured way /// to tie the types to be decoded to the mask necessary to query them. #[derive(Debug)] pub struct Mask(std::marker::PhantomData<(FIRST, SECOND, THIRD)>); macro_rules! add_segments { ($($segment:tt),+) => { paste::paste! { $( #[doc = concat!("Mask for ", stringify!($segment), " static file segment. See [`Mask`] for more.")] #[derive(Debug)] // TODO: remove next attribute when nightly is fixed (ie. does // not return wrong warnings for never constructed structs). #[allow(dead_code)] pub struct [<$segment Mask>](Mask); )+ } }; } add_segments!(Header, Receipt, Transaction); /// Trait for specifying a mask to select one column value. pub trait ColumnSelectorOne { /// First desired column value type FIRST: Decompress; /// Mask to obtain desired values, should correspond to the order of columns in a `static_file`. const MASK: usize; } /// Trait for specifying a mask to select two column values. pub trait ColumnSelectorTwo { /// First desired column value type FIRST: Decompress; /// Second desired column value type SECOND: Decompress; /// Mask to obtain desired values, should correspond to the order of columns in a `static_file`. const MASK: usize; } /// Trait for specifying a mask to select three column values. pub trait ColumnSelectorThree { /// First desired column value type FIRST: Decompress; /// Second desired column value type SECOND: Decompress; /// Third desired column value type THIRD: Decompress; /// Mask to obtain desired values, should correspond to the order of columns in a `static_file`. const MASK: usize; } #[macro_export] /// Add mask to select `N` column values from a specific static file segment row. macro_rules! add_static_file_mask { ($mask_struct:tt, $type1:ty, $mask:expr) => { impl ColumnSelectorOne for $mask_struct<$type1> { type FIRST = $type1; const MASK: usize = $mask; } }; ($mask_struct:tt, $type1:ty, $type2:ty, $mask:expr) => { impl ColumnSelectorTwo for $mask_struct<$type1, $type2> { type FIRST = $type1; type SECOND = $type2; const MASK: usize = $mask; } }; ($mask_struct:tt, $type1:ty, $type2:ty, $type3:ty, $mask:expr) => { impl ColumnSelectorThree for $mask_struct<$type1, $type2, $type3> { type FIRST = $type1; type SECOND = $type2; type THIRD = $type3; const MASK: usize = $mask; } }; }