Add functions to SuccessArgs for getting variant arguments

Add try_get_args* functions to SuccessArgs for extracting variant
arguments if the variant matches.

Signed-off-by: Imre Kis <imre.kis@arm.com>
Change-Id: Iec229c4bf767f9f0d31feea2a392b8b7bc693d73
diff --git a/src/lib.rs b/src/lib.rs
index 4ef3560..349b457 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -49,6 +49,8 @@
     InvalidVmId(u32),
     #[error("Invalid FF-A Partition Info Get Flag {0}")]
     InvalidPartitionInfoGetFlag(u32),
+    #[error("Invalid success argument variant")]
+    InvalidSuccessArgsVariant,
 }
 
 impl From<Error> for FfaError {
@@ -66,7 +68,8 @@
             | Error::InvalidNotificationSetFlag(_)
             | Error::InvalidVmId(_)
             | Error::UnrecognisedWarmBootType(_)
-            | Error::InvalidPartitionInfoGetFlag(_) => Self::InvalidParameters,
+            | Error::InvalidPartitionInfoGetFlag(_)
+            | Error::InvalidSuccessArgsVariant => Self::InvalidParameters,
         }
     }
 }
@@ -195,7 +198,10 @@
     }
 }
 
-/// Arguments for the `FFA_SUCCESS` interface.
+/// Generic arguments of the `FFA_SUCCESS` interface. The interpretation of the arguments depends on
+/// the interface that initiated the request. The application code has knowledge of the request, so
+/// it has to convert `SuccessArgs` into/from a specific success args structure that matches the
+/// request.
 #[derive(Debug, Eq, PartialEq, Clone, Copy)]
 pub enum SuccessArgs {
     Args32([u32; 6]),
@@ -203,6 +209,35 @@
     Args64_2([u64; 16]),
 }
 
+impl SuccessArgs {
+    fn try_get_args32(self) -> Result<[u32; 6], Error> {
+        match self {
+            SuccessArgs::Args32(args) => Ok(args),
+            SuccessArgs::Args64(_) | SuccessArgs::Args64_2(_) => {
+                Err(Error::InvalidSuccessArgsVariant)
+            }
+        }
+    }
+
+    fn try_get_args64(self) -> Result<[u64; 6], Error> {
+        match self {
+            SuccessArgs::Args64(args) => Ok(args),
+            SuccessArgs::Args32(_) | SuccessArgs::Args64_2(_) => {
+                Err(Error::InvalidSuccessArgsVariant)
+            }
+        }
+    }
+
+    fn try_get_args64_2(self) -> Result<[u64; 16], Error> {
+        match self {
+            SuccessArgs::Args64_2(args) => Ok(args),
+            SuccessArgs::Args32(_) | SuccessArgs::Args64(_) => {
+                Err(Error::InvalidSuccessArgsVariant)
+            }
+        }
+    }
+}
+
 /// Entrypoint address argument for `FFA_SECONDARY_EP_REGISTER` interface.
 #[derive(Debug, Eq, PartialEq, Clone, Copy)]
 pub enum SecondaryEpRegisterAddr {