diff options
Diffstat (limited to 'src/macros.rs')
-rw-r--r-- | src/macros.rs | 128 |
1 files changed, 117 insertions, 11 deletions
diff --git a/src/macros.rs b/src/macros.rs index 7d6ac8df..927e7e7c 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -83,9 +83,9 @@ macro_rules! libc_bitflags { macro_rules! libc_enum { // Exit rule. (@make_enum + name: $BitFlags:ident, { $v:vis - name: $BitFlags:ident, attrs: [$($attrs:tt)*], entries: [$($entries:tt)*], } @@ -97,38 +97,98 @@ macro_rules! libc_enum { } }; + // Exit rule including TryFrom + (@make_enum + name: $BitFlags:ident, + { + $v:vis + attrs: [$($attrs:tt)*], + entries: [$($entries:tt)*], + from_type: $repr:path, + try_froms: [$($try_froms:tt)*] + } + ) => { + $($attrs)* + #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + $v enum $BitFlags { + $($entries)* + } + #[allow(unused_doc_comment)] + impl ::std::convert::TryFrom<$repr> for $BitFlags { + type Error = $crate::Error; + fn try_from(x: $repr) -> $crate::Result<Self> { + match x { + $($try_froms)* + _ => Err($crate::Error::EINVAL) + } + } + } + }; + // Done accumulating. (@accumulate_entries + name: $BitFlags:ident, + { + $v:vis + attrs: $attrs:tt, + }, + $entries:tt, + $try_froms:tt; + ) => { + libc_enum! { + @make_enum + name: $BitFlags, + { + $v + attrs: $attrs, + entries: $entries, + } + } + }; + + // Done accumulating and want TryFrom + (@accumulate_entries + name: $BitFlags:ident, { $v:vis - name: $BitFlags:ident, attrs: $attrs:tt, + from_type: $repr:path, }, - $entries:tt; + $entries:tt, + $try_froms:tt; ) => { libc_enum! { @make_enum + name: $BitFlags, { $v - name: $BitFlags, attrs: $attrs, entries: $entries, + from_type: $repr, + try_froms: $try_froms } } }; // Munch an attr. (@accumulate_entries + name: $BitFlags:ident, $prefix:tt, - [$($entries:tt)*]; + [$($entries:tt)*], + [$($try_froms:tt)*]; #[$attr:meta] $($tail:tt)* ) => { libc_enum! { @accumulate_entries + name: $BitFlags, $prefix, [ $($entries)* #[$attr] + ], + [ + $($try_froms)* + #[$attr] ]; $($tail)* } @@ -136,32 +196,47 @@ macro_rules! libc_enum { // Munch last ident if not followed by a comma. (@accumulate_entries + name: $BitFlags:ident, $prefix:tt, - [$($entries:tt)*]; + [$($entries:tt)*], + [$($try_froms:tt)*]; $entry:ident ) => { libc_enum! { @accumulate_entries + name: $BitFlags, $prefix, [ $($entries)* $entry = libc::$entry, + ], + [ + $($try_froms)* + libc::$entry => Ok($BitFlags::$entry), ]; } }; // Munch an ident; covers terminating comma case. (@accumulate_entries + name: $BitFlags:ident, $prefix:tt, - [$($entries:tt)*]; - $entry:ident, $($tail:tt)* + [$($entries:tt)*], + [$($try_froms:tt)*]; + $entry:ident, + $($tail:tt)* ) => { libc_enum! { @accumulate_entries + name: $BitFlags, $prefix, [ $($entries)* $entry = libc::$entry, + ], + [ + $($try_froms)* + libc::$entry => Ok($BitFlags::$entry), ]; $($tail)* } @@ -169,16 +244,24 @@ macro_rules! libc_enum { // Munch an ident and cast it to the given type; covers terminating comma. (@accumulate_entries + name: $BitFlags:ident, $prefix:tt, - [$($entries:tt)*]; - $entry:ident as $ty:ty, $($tail:tt)* + [$($entries:tt)*], + [$($try_froms:tt)*]; + $entry:ident as $ty:ty, + $($tail:tt)* ) => { libc_enum! { @accumulate_entries + name: $BitFlags, $prefix, [ $($entries)* $entry = libc::$entry as $ty, + ], + [ + $($try_froms)* + libc::$entry as $ty => Ok($BitFlags::$entry), ]; $($tail)* } @@ -193,11 +276,34 @@ macro_rules! libc_enum { ) => { libc_enum! { @accumulate_entries + name: $BitFlags, + { + $v + attrs: [$(#[$attr])*], + }, + [], + []; + $($vals)* + } + }; + + // Entry rule including TryFrom + ( + $(#[$attr:meta])* + $v:vis enum $BitFlags:ident { + $($vals:tt)* + } + impl TryFrom<$repr:path> + ) => { + libc_enum! { + @accumulate_entries + name: $BitFlags, { $v - name: $BitFlags, attrs: [$(#[$attr])*], + from_type: $repr, }, + [], []; $($vals)* } |