binder_rs: Add in-place deserialization methods

This adds deserialize_from methods to the Deserialize
and DeserializeOption traits in libbinder_rs that perform
in-place deserialization of values on top of existing objects.
The new methods are used for partial deserialization of parcelables
in the AIDL compiler.
Also adds a helper impl_deserialize_for_parcelable! helper macro.

Bug: 186724059
Test: m
Change-Id: I9fcbd4c7fa4ab85d8ab84792c9c5595ee149879f
diff --git a/libs/binder/rust/src/parcel.rs b/libs/binder/rust/src/parcel.rs
index 6c34824..ef84ade 100644
--- a/libs/binder/rust/src/parcel.rs
+++ b/libs/binder/rust/src/parcel.rs
@@ -219,6 +219,13 @@
         D::deserialize(self)
     }
 
+    /// Attempt to read a type that implements [`Deserialize`] from this
+    /// `Parcel` onto an existing value. This operation will overwrite the old
+    /// value partially or completely, depending on how much data is available.
+    pub fn read_onto<D: Deserialize>(&self, x: &mut D) -> Result<()> {
+        x.deserialize_from(self)
+    }
+
     /// Read a vector size from the `Parcel` and resize the given output vector
     /// to be correctly sized for that amount of data.
     ///
diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs
index f57788b..956ecfe 100644
--- a/libs/binder/rust/src/parcel/parcelable.rs
+++ b/libs/binder/rust/src/parcel/parcelable.rs
@@ -39,6 +39,14 @@
 pub trait Deserialize: Sized {
     /// Deserialize an instance from the given [`Parcel`].
     fn deserialize(parcel: &Parcel) -> Result<Self>;
+
+    /// Deserialize an instance from the given [`Parcel`] onto the
+    /// current object. This operation will overwrite the old value
+    /// partially or completely, depending on how much data is available.
+    fn deserialize_from(&mut self, parcel: &Parcel) -> Result<()> {
+        *self = Self::deserialize(parcel)?;
+        Ok(())
+    }
 }
 
 /// Helper trait for types that can be serialized as arrays.
@@ -184,6 +192,14 @@
             parcel.read().map(Some)
         }
     }
+
+    /// Deserialize an Option of this type from the given [`Parcel`] onto the
+    /// current object. This operation will overwrite the current value
+    /// partially or completely, depending on how much data is available.
+    fn deserialize_option_from(this: &mut Option<Self>, parcel: &Parcel) -> Result<()> {
+        *this = Self::deserialize_option(parcel)?;
+        Ok(())
+    }
 }
 
 /// Callback to allocate a vector for parcel array read functions.
@@ -677,6 +693,75 @@
     fn deserialize(parcel: &Parcel) -> Result<Self> {
         DeserializeOption::deserialize_option(parcel)
     }
+
+    fn deserialize_from(&mut self, parcel: &Parcel) -> Result<()> {
+        DeserializeOption::deserialize_option_from(self, parcel)
+    }
+}
+
+/// Implement `Deserialize` trait and friends for a parcelable
+///
+/// This is an internal macro used by the AIDL compiler to implement
+/// `Deserialize`, `DeserializeArray` and `DeserializeOption` for
+/// structured parcelables. The target type must implement a
+/// `deserialize_parcelable` method with the following signature:
+/// ```no_run
+/// fn deserialize_parcelable(
+///     &mut self,
+///     parcel: &binder::parcel::Parcelable,
+/// ) -> binder::Result<()> {
+///     // ...
+/// }
+/// ```
+#[macro_export]
+macro_rules! impl_deserialize_for_parcelable {
+    ($parcelable:ident) => {
+        impl $crate::parcel::Deserialize for $parcelable {
+            fn deserialize(
+                parcel: &$crate::parcel::Parcel,
+            ) -> $crate::Result<Self> {
+                $crate::parcel::DeserializeOption::deserialize_option(parcel)
+                    .transpose()
+                    .unwrap_or(Err($crate::StatusCode::UNEXPECTED_NULL))
+            }
+            fn deserialize_from(
+                &mut self,
+                parcel: &$crate::parcel::Parcel,
+            ) -> $crate::Result<()> {
+                let status: i32 = parcel.read()?;
+                if status == 0 {
+                    Err($crate::StatusCode::UNEXPECTED_NULL)
+                } else {
+                    self.deserialize_parcelable(parcel)
+                }
+            }
+        }
+
+        impl $crate::parcel::DeserializeArray for $parcelable {}
+
+        impl $crate::parcel::DeserializeOption for $parcelable {
+            fn deserialize_option(
+                parcel: &$crate::parcel::Parcel,
+            ) -> $crate::Result<Option<Self>> {
+                let mut result = None;
+                Self::deserialize_option_from(&mut result, parcel)?;
+                Ok(result)
+            }
+            fn deserialize_option_from(
+                this: &mut Option<Self>,
+                parcel: &$crate::parcel::Parcel,
+            ) -> $crate::Result<()> {
+                let status: i32 = parcel.read()?;
+                if status == 0 {
+                    *this = None;
+                    Ok(())
+                } else {
+                    this.get_or_insert_with(Self::default)
+                        .deserialize_parcelable(parcel)
+                }
+            }
+        }
+    }
 }
 
 #[test]