Keystore 2.0: Refactor permissions. 2/5

Move implement_permission macro to libkeystore2_selinux.

Test: keystore2_test
Bug: 203555519

Change-Id: I85d2411872aecaaa12876f848e9205431a8b0fa4
diff --git a/keystore2/src/permission.rs b/keystore2/src/permission.rs
index 97b241f..fad5636 100644
--- a/keystore2/src/permission.rs
+++ b/keystore2/src/permission.rs
@@ -18,23 +18,18 @@
 //! It also provides KeystorePerm and KeyPerm as convenience wrappers for the SELinux permission
 //! defined by keystore2 and keystore2_key respectively.
 
+use crate::error::Error as KsError;
 use android_system_keystore2::aidl::android::system::keystore2::{
     Domain::Domain, KeyDescriptor::KeyDescriptor, KeyPermission::KeyPermission,
 };
-
+use anyhow::Context as AnyhowContext;
+use keystore2_selinux as selinux;
+use lazy_static::lazy_static;
+use selinux::{implement_permission, Backend};
 use std::cmp::PartialEq;
 use std::convert::From;
 use std::ffi::CStr;
 
-use crate::error::Error as KsError;
-use keystore2_selinux as selinux;
-
-use anyhow::Context as AnyhowContext;
-
-use selinux::Backend;
-
-use lazy_static::lazy_static;
-
 // Replace getcon with a mock in the test situation
 #[cfg(not(test))]
 use selinux::getcon;
@@ -206,240 +201,6 @@
     }
 );
 
-/// This macro implements an enum with values mapped to SELinux permission names.
-/// The below example wraps the enum MyPermission in the tuple struct `MyPerm` and implements
-///  * From<i32> and Into<i32> are implemented. Where the implementation of From maps
-///    any variant not specified to the default.
-///  * Every variant has a constructor with a name corresponding to its lower case SELinux string
-///    representation.
-///  * `MyPermission::to_selinux(&self)` returns the SELinux string representation of the
-///    corresponding permission.
-///  * An implicit default values `MyPermission::None` is created with a numeric representation
-///    of `0` and a string representation of `"none"`.
-///  * Specifying a value is optional. If the value is omitted it is set to the value of the
-///    previous variant left shifted by 1.
-///
-/// ## Example
-/// ```
-/// implement_permission!(
-///     /// MyPermission documentation.
-///     #[derive(Clone, Copy, Debug, Eq, PartialEq)]
-///     pub enum MyPermission {
-///         #[selinux(name = foo)]
-///         Foo = 1,
-///         #[selinux(name = bar)]
-///         Bar = 2,
-///         #[selinux(name = snafu)]
-///         Snafu, // Implicit value: MyPermission::Bar << 1 = 4
-///     }
-/// );
-/// ```
-macro_rules! implement_permission {
-    (
-        $(#[$enum_meta:meta])*
-        $enum_vis:vis enum $enum_name:ident {
-            $(
-                $(#[$($emeta:tt)+])*
-                $vname:ident$( = $vval:tt)?
-            ),* $(,)?
-        }
-    ) => {
-        implement_permission!{
-            @extract_attr
-            $(#[$enum_meta])*
-            $enum_vis enum $enum_name {
-                1
-                []
-                [$(
-                    [] [$(#[$($emeta)+])*]
-                    $vname$( = $vval)?,
-                )*]
-            }
-        }
-    };
-
-    (
-        @extract_attr
-        $(#[$enum_meta:meta])*
-        $enum_vis:vis enum $enum_name:ident {
-            $next_val:tt
-            [$($out:tt)*]
-            [
-                [$(#[$mout:meta])*]
-                [
-                    #[selinux(name = $selinux_name:ident)]
-                    $(#[$($mtail:tt)+])*
-                ]
-                $vname:ident = $vval:tt,
-                $($tail:tt)*
-            ]
-        }
-    ) => {
-        implement_permission!{
-            @extract_attr
-            $(#[$enum_meta])*
-            $enum_vis enum $enum_name {
-                ($vval << 1)
-                [
-                    $($out)*
-                    $(#[$mout])*
-                    $(#[$($mtail)+])*
-                    $selinux_name $vname = $vval,
-                ]
-                [$($tail)*]
-            }
-        }
-    };
-
-    (
-        @extract_attr
-        $(#[$enum_meta:meta])*
-        $enum_vis:vis enum $enum_name:ident {
-            $next_val:tt
-            [$($out:tt)*]
-            [
-                [$(#[$mout:meta])*]
-                [
-                    #[selinux(name = $selinux_name:ident)]
-                    $(#[$($mtail:tt)+])*
-                ]
-                $vname:ident,
-                $($tail:tt)*
-            ]
-        }
-    ) => {
-        implement_permission!{
-            @extract_attr
-            $(#[$enum_meta])*
-            $enum_vis enum $enum_name {
-                ($next_val << 1)
-                [
-                    $($out)*
-                    $(#[$mout])*
-                    $(#[$($mtail)+])*
-                    $selinux_name $vname = $next_val,
-                ]
-                [$($tail)*]
-            }
-        }
-    };
-
-
-    (
-        @extract_attr
-        $(#[$enum_meta:meta])*
-        $enum_vis:vis enum $enum_name:ident {
-            $next_val:tt
-            [$($out:tt)*]
-            [
-                [$(#[$mout:meta])*]
-                [
-                    #[$front:meta]
-                    $(#[$($mtail:tt)+])*
-                ]
-                $vname:ident$( = $vval:tt)?,
-                $($tail:tt)*
-            ]
-        }
-    ) => {
-        implement_permission!{
-            @extract_attr
-            $(#[$enum_meta])*
-            $enum_vis enum $enum_name {
-                $next_val
-                [$($out)*]
-                [
-                    [
-                        $(#[$mout])*
-                        #[$front]
-                    ]
-                    [$(#[$($mtail)+])*]
-                    $vname$( = $vval)?,
-                    $($tail)*
-                ]
-            }
-        }
-    };
-
-    (
-        @extract_attr
-        $(#[$enum_meta:meta])*
-        $enum_vis:vis enum $enum_name:ident {
-            $next_val:tt
-            [$($out:tt)*]
-            []
-        }
-    ) => {
-        implement_permission!{
-            @spill
-            $(#[$enum_meta])*
-            $enum_vis enum $enum_name {
-                $($out)*
-            }
-        }
-    };
-
-    (
-        @spill
-        $(#[$enum_meta:meta])*
-        $enum_vis:vis enum $enum_name:ident {
-            $(
-                $(#[$emeta:meta])*
-                $selinux_name:ident $vname:ident = $vval:tt,
-            )*
-        }
-    ) => {
-        $(#[$enum_meta])*
-        $enum_vis enum $enum_name {
-            /// The default variant of an enum.
-            None = 0,
-            $(
-                $(#[$emeta])*
-                $vname = $vval,
-            )*
-        }
-
-        impl From<i32> for $enum_name {
-            #[allow(non_upper_case_globals)]
-            fn from (p: i32) -> Self {
-                // Creating constants forces the compiler to evaluate the value expressions
-                // so that they can be used in the match statement below.
-                $(const $vname: i32 = $vval;)*
-                match p {
-                    0 => Self::None,
-                    $($vname => Self::$vname,)*
-                    _ => Self::None,
-                }
-            }
-        }
-
-        impl From<$enum_name> for i32 {
-            fn from(p: $enum_name) -> i32 {
-                p as i32
-            }
-        }
-
-        impl $enum_name {
-
-            /// Returns a string representation of the permission as required by
-            /// `selinux::check_access`.
-            pub fn to_selinux(self) -> &'static str {
-                match self {
-                    Self::None => &"none",
-                    $(Self::$vname => stringify!($selinux_name),)*
-                }
-            }
-
-            /// Creates an instance representing a permission with the same name.
-            pub const fn none() -> Self { Self::None }
-            $(
-                /// Creates an instance representing a permission with the same name.
-                pub const fn $selinux_name() -> Self { Self::$vname }
-            )*
-        }
-    };
-}
-
 implement_permission!(
     /// KeystorePerm provides a convenient abstraction from the SELinux class `keystore2`.
     /// Using the implement_permission macro we get the same features as `KeyPerm`.