#[macro_export]
macro_rules! type_ {
(!) => (Type::Never);
(()) => (Type::Unit);
(bool) => (Type::Bool);
(usize) => (Type::Integer { signed: false, bits: None });
(isize) => (Type::Integer { signed: true, bits: None });
(u8) => (Type::Integer { signed: false, bits: Some(8) });
(i8) => (Type::Integer { signed: true, bits: Some(8) });
(u16) => (Type::Integer { signed: false, bits: Some(16) });
(i16) => (Type::Integer { signed: true, bits: Some(16) });
(u32) => (Type::Integer { signed: false, bits: Some(32) });
(i32) => (Type::Integer { signed: true, bits: Some(32) });
(u64) => (Type::Integer { signed: false, bits: Some(64) });
(i64) => (Type::Integer { signed: true, bits: Some(64) });
([$len:tt; $($type:tt)*]) => {
Type::Array { type_: Box::new(type_!($($type)*)), length: $len }
};
(*const $($type:tt)*) => (type_!(*false $($type)*));
(*mut $($type:tt)*) => (type_!(*true $($type)*));
(*$mut:tt void) => (Type::Pointer { mutable: $mut, type_: None });
(*$mut:tt $($type:tt)*) => {
Type::Pointer { mutable: $mut, type_: Some(Box::new(type_!($($type)*))) }
};
(fn $fields:tt) => (Type::Function { params: fields!($fields) });
}
#[macro_export]
macro_rules! docs {
($(#[doc = $doc:literal])*) => (vec![$($doc.into()),*]);
}
#[macro_export]
macro_rules! variants {
($input:tt) => (variants!($input []));
({ $(#[doc = $doc:literal])* $name:ident = $value:expr, $($input:tt)* }
[$($output:tt)*]) => (variants! {
{ $($input)* } [$($output)* Variant {
docs: vec![$($doc.into()),*],
name: stringify!($name).into(),
value: $value,
},]
});
({} [$($output:tt)*]) => (vec![$($output)*]);
}
#[macro_export]
macro_rules! fields {
($input:tt) => (fields!($input []));
({ $(#[doc = $doc:literal])* $(#[cfg($cfg:meta)])* $name:ident: $($input:tt)* } $output:tt
) => (fields! {
[$($doc)*] [$($cfg)*] $name [] { $($input)* } $output
});
($doc:tt $cfg:tt $name:ident $type:tt {} $output:tt) => (fields! {
$doc $cfg $name $type { , } $output
});
([$($doc:literal)*] [$($cfg:meta)*] $name:ident [$($type:tt)*] { , $($input:tt)* }
[$($output:tt)*]) => (fields! {
{ $($input)* } [
$($output)*
$(#[cfg($cfg)])*
Field {
docs: vec![$($doc.into()),*],
name: stringify!($name).into(),
type_: type_!($($type)*),
},
]
});
($doc:tt $cfg:tt $name:ident [$($type:tt)*] { $x:tt $($input:tt)* } $output:tt) => (fields! {
$doc $cfg $name [$($type)* $x] { $($input)* } $output
});
({} [$($output:tt)*]) => (vec![$($output)*]);
}
#[macro_export]
macro_rules! item {
($(#[doc = $doc:literal])* enum $name:ident $variants:tt) => {
Item::Enum(Enum {
docs: vec![$($doc.into()),*],
name: stringify!($name).into(),
variants: variants!($variants),
})
};
($(#[doc = $doc:literal])* struct $name:ident $fields:tt) => {
Item::Struct(Struct {
docs: vec![$($doc.into()),*],
name: stringify!($name).into(),
fields: fields!($fields),
})
};
($(#[doc = $doc:literal])* fn $name:ident $link:literal $params:tt -> $($result:tt)*) => {
Item::Fn(Fn {
docs: vec![$($doc.into()),*],
name: stringify!($name).into(),
link: $link.into(),
params: fields!($params),
result: type_!($($result)*),
})
};
}