Loading libs/binder/rust/src/parcel.rs +7 −0 Original line number Diff line number Diff line Loading @@ -219,6 +219,13 @@ impl Parcel { 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. /// Loading libs/binder/rust/src/parcel/parcelable.rs +85 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,14 @@ pub trait Serialize { 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. Loading Loading @@ -184,6 +192,14 @@ pub trait DeserializeOption: Deserialize { 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. Loading Loading @@ -677,6 +693,75 @@ impl<T: DeserializeOption> Deserialize for Option<T> { 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] Loading Loading
libs/binder/rust/src/parcel.rs +7 −0 Original line number Diff line number Diff line Loading @@ -219,6 +219,13 @@ impl Parcel { 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. /// Loading
libs/binder/rust/src/parcel/parcelable.rs +85 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,14 @@ pub trait Serialize { 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. Loading Loading @@ -184,6 +192,14 @@ pub trait DeserializeOption: Deserialize { 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. Loading Loading @@ -677,6 +693,75 @@ impl<T: DeserializeOption> Deserialize for Option<T> { 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] Loading