Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save novafacing/aad21dcad051c6f2f616895844eceef7 to your computer and use it in GitHub Desktop.
Save novafacing/aad21dcad051c6f2f616895844eceef7 to your computer and use it in GitHub Desktop.
macro_rules! from_primitive_patterns {
{
$match_ty:ty,
$match_val:expr,
@parse {$($eout:tt)*},
$variant:ident = $value:expr,
$($rest:tt)*
} => {
from_primitive_patterns! {
$match_ty,
$match_val,
@parse {
$($eout)*
$value => Some(Self::$variant),
},
$($rest)*
}
};
{
$match_ty:ty,
$match_val:expr,
@parse {$($eout:tt)*},
$variant:ident($param:ty),
$($rest:tt)*
} => {
from_primitive_patterns! {
$match_ty,
$match_val,
@parse {
$($eout)*
other => Some(Self::$variant(other as $param)),
},
$($rest)*
}
};
{
$match_ty:ty,
$match_val:expr,
@parse {$($eout:tt)*},
} => {
match $match_val {
$($eout)*
}
};
}
macro_rules! to_primitive_patterns {
{
$self:ident,
$match_ty:ty,
@parse {$($eout:tt)*},
$variant:ident = $value:expr,
$($rest:tt)*
} => {
to_primitive_patterns! {
$self,
$match_ty,
@parse {
$($eout)*
Self::$variant => Some($value),
},
$($rest)*
}
};
{
$self:ident,
$match_ty:ty,
@parse {$($eout:tt)*},
$variant:ident($param:ty),
$($rest:tt)*
} => {
to_primitive_patterns! {
$self,
$match_ty,
@parse {
$($eout)*
Self::$variant(value) => Some(*value as $match_ty),
},
$($rest)*
}
};
{
$self:ident,
$match_ty:ty,
@parse {$($eout:tt)*},
} => {
match $self {
$($eout)*
}
};
}
macro_rules! parse_enum_variant {
{
$(#[$enum_meta:meta])*,
$vis:vis,
$name:ident,
$(<$($generic_param:tt),*>)?,
@where_clauses {$($where:tt)*},
@parse {$($eout:tt)*},
$(#[$variant_meta:meta])+ $($rest:tt)*
} => {
parse_enum_variant! {
$(#[$enum_meta])*,
$vis,
$name,
$(<$($generic_param),*>)?,
@where_clauses {$($where)*},
@parse {
$($eout)*
$(#[$variant_meta])+
},
$($rest)*
}
};
{
$(#[$enum_meta:meta])*,
$vis:vis,
$name:ident,
$(<$($generic_param:tt),*>)?,
@where_clauses {$($where:tt)*},
@parse {$($eout:tt)*},
$variant:ident,
$($rest:tt)*
} => {
parse_enum_variant! {
$(#[$enum_meta])*,
$vis,
$name,
$(<$($generic_param),*>)?,
@where_clauses {$($where)*},
@parse {
$($eout)*
$variant,
},
$($rest)*
}
};
{
$(#[$enum_meta:meta])*,
$vis:vis,
$name:ident,
$(<$($generic_param:tt),*>)?,
@where_clauses {$($where:tt)*},
@parse {$($eout:tt)*},
$variant:ident = $value:expr,
$($rest:tt)*
} => {
parse_enum_variant!{
$(#[$enum_meta])*,
$vis,
$name,
$(<$($generic_param),*>)?,
@where_clauses {$($where)*},
@parse {
$($eout)*
$variant = $value,
},
$($rest)*
}
};
{
$(#[$enum_meta:meta])*,
$vis:vis,
$name:ident,
$(<$($generic_param:tt),*>)?,
@where_clauses {$($where:tt)*},
@parse {$($eout:tt)*},
$variant:ident($param:ty),
$($rest:tt)*
} => {
parse_enum_variant!{
$(#[$enum_meta])*,
$vis,
$name,
$(<$($generic_param),*>)?,
@where_clauses {$($where)*},
@parse {
$($eout)*
$variant($param),
},
$($rest)*
}
};
{
$(#[$enum_meta:meta])*,
$vis:vis,
$name:ident,
$(<$($generic_param:tt),*>)?,
@where_clauses {$($where:tt)*},
@parse {$($eout:tt)*},
$variant:ident { $($fields:tt)* },
$($rest:tt)*
} => {
parse_enum_variant!{
$(#[$enum_meta])*,
$vis,
$name,
$(<$($generic_param),*>)?,
@where_clauses {$($where)*},
@parse {
$($eout)*
$variant { $($fields)* },
},
$($rest)*
}
};
{
$(#[$enum_meta:meta])*,
$vis:vis,
$name:ident,
$(<$($generic_param:tt),*>)?,
@where_clauses {$($where:tt)*},
@parse {$($eout:tt)*} $(,)*
} => {
$(#[$enum_meta])*
$vis enum $name
$(<$($generic_param),*>)?
$($where)*
{
$($eout)*
}
impl $(<$($generic_param),*>)? num_traits::FromPrimitive for $name $(<$($generic_param),*>)? $($where:tt)* {
fn from_i64(n: i64) -> Option<Self> {
from_primitive_patterns! {
i64,
n,
@parse {},
$($eout)*
}
}
fn from_u64(n: u64) -> Option<Self> {
from_primitive_patterns! {
u64,
n,
@parse {},
$($eout)*
}
}
}
impl $(<$($generic_param),*>)? num_traits::ToPrimitive for $name $(<$($generic_param),*>)? $($where:tt)* {
fn to_i64(&self) -> Option<i64> {
to_primitive_patterns! {
self,
i64,
@parse {},
$($eout)*
}
}
fn to_u64(&self) -> Option<u64> {
to_primitive_patterns! {
self,
u64,
@parse {},
$($eout)*
}
}
}
};
{
$(#[$enum_meta:meta])*,
$vis:vis,
$name:ident,
$(<$($generic_param:tt),*>)?,
@where_clauses {$($where:tt)*},
@parse {$($eout:tt)*} $(,)*
} => {
$(#[$enum_meta])*
$vis enum $name
$(<$($generic_param),*>)?
$($where)*
{
$($eout)*
}
};
{
$(#[$enum_meta:meta])*,
$vis:vis,
$name:ident,
$(<$($generic_param:tt),*>)?,
@where_clauses {$($where:tt)*},
@parse {$($eout:tt)*} $(,)*
} => {
$(#[$enum_meta])*
$vis enum $name
$(<$($generic_param),*>)?
$($where)*
{
$($eout)*
}
};
{
$(#[$enum_meta:meta])*,
$vis:vis,
$name:ident,
$(<$($generic_param:tt),*>)?,
@where_clauses {$($where:tt)*},
@parse {$($eout:tt)*} $(,)*
} => {
$(#[$enum_meta])*
$vis enum $name
$(<$($generic_param),*>)?
$($where)*
{
$($eout)*
}
};
}
#[macro_export]
macro_rules! convert_primitive {
(
$(#[$enum_meta:meta])*
$vis:vis enum $enum_name:ident
$(<$($generic_param:tt),*>)?
{
$($variants:tt)*
}
) => {
parse_enum_variant! {
$(#[$enum_meta])*,
$vis,
$enum_name,
$(<$($generic_param),*>)?,
@where_clauses {},
@parse {}, $($variants)*
}
};
(
$(#[$enum_meta:meta])*
$vis:vis enum $enum_name:ident
$(<$($generic_param:tt),*>)?
where
$where_clause:tt $(<$($where_generic_param:tt),*>)?:
$where_clause_bound:tt $(<$($where_clause_bound_generic_param:tt),*>)?
$(+ $where_clause_bound_plus:tt $(<$($where_clause_bound_generic_param_plus:tt),*>)?)*
$(, $more_where_clause:tt $(<$($more_where_generic_param:tt),*>)?:
$more_where_clause_bound:tt $(<$($more_where_clause_bound_generic_param:tt),*>)?
$(+ $more_where_clause_bound_plus:tt $(<$($more_where_clause_bounds_generic_param_plus:tt),*>)?)* )*
{
$($variants:tt)*
}
) => {
parse_enum_variant! {
$(#[$enum_meta])*,
$vis,
$enum_name,
$(<$($generic_param),*>)?,
@where_clauses {
where
$where_clause $(<$($where_generic_param),*>)?:
$where_clause_bound $(<$($where_clause_bound_generic_param),*>)?
$(+ $where_clause_bound_plus $(<$($where_clause_bound_generic_param_plus),*>)?)*
$(, $more_where_clause $(<$($more_where_generic_param),*>)?:
$more_where_clause_bound $(<$($more_where_clause_bound_generic_param),*>)?
$(+ $more_where_clause_bound_plus $(<$($more_where_clause_bounds_generic_param_plus),*>)?)* )*
},
@parse {}, $($variants)*
}
};
}
convert_primitive! {
#[allow(non_camel_case_types)]
#[repr(u32)]
#[derive(Debug, Clone, Copy)]
pub enum Elf32LESectionHeaderTypeSystemV {
// In practice, System V ELF files frequently define the GNU extensions
// as well, so we include them here.
ATTRIBUTES = 0x6ffffff5,
HASH = 0x6ffffff6,
LIBLIST = 0x6ffffff7,
VERDEF = 0x6ffffffd,
VERNEED = 0x6ffffffe,
VERSYM = 0x6fffffff,
Unknown(u32),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment