1a34a8711Sopenharmony_ci// Copyright (C) 2024 Huawei Device Co., Ltd. 2a34a8711Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 3a34a8711Sopenharmony_ci// you may not use this file except in compliance with the License. 4a34a8711Sopenharmony_ci// You may obtain a copy of the License at 5a34a8711Sopenharmony_ci// 6a34a8711Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 7a34a8711Sopenharmony_ci// 8a34a8711Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 9a34a8711Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 10a34a8711Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11a34a8711Sopenharmony_ci// See the License for the specific language governing permissions and 12a34a8711Sopenharmony_ci// limitations under the License. 13a34a8711Sopenharmony_ci 14a34a8711Sopenharmony_ci 15a34a8711Sopenharmony_ciuse super::msg::MsgParcel; 16a34a8711Sopenharmony_ciuse crate::errors::IpcResult; 17a34a8711Sopenharmony_ci/// Data structures that can be serialized and written by MsgPracel 18a34a8711Sopenharmony_ci/// 19a34a8711Sopenharmony_ci/// # Example: 20a34a8711Sopenharmony_ci/// 21a34a8711Sopenharmony_ci/// ```rust 22a34a8711Sopenharmony_ci/// use ipc::parcel::{MsgParcel, Serialize}; 23a34a8711Sopenharmony_ci/// use ipc::IpcResult; 24a34a8711Sopenharmony_ci/// 25a34a8711Sopenharmony_ci/// struct Foo { 26a34a8711Sopenharmony_ci/// a: Vec<i32>, 27a34a8711Sopenharmony_ci/// b: String, 28a34a8711Sopenharmony_ci/// } 29a34a8711Sopenharmony_ci/// 30a34a8711Sopenharmony_ci/// impl Serialize for Foo { 31a34a8711Sopenharmony_ci/// fn serialize(&self, parcel: &mut MsgParcel) -> IpcResult<()> { 32a34a8711Sopenharmony_ci/// parcel.write(&self.a)?; 33a34a8711Sopenharmony_ci/// parcel.write(&self.b)?; 34a34a8711Sopenharmony_ci/// Ok(()) 35a34a8711Sopenharmony_ci/// } 36a34a8711Sopenharmony_ci/// } 37a34a8711Sopenharmony_ci/// ``` 38a34a8711Sopenharmony_cipub trait Serialize { 39a34a8711Sopenharmony_ci /// serialize and write into MsgParcel 40a34a8711Sopenharmony_ci fn serialize(&self, parcel: &mut MsgParcel) -> IpcResult<()>; 41a34a8711Sopenharmony_ci} 42a34a8711Sopenharmony_ci 43a34a8711Sopenharmony_ci/// Data structures that can be deserialized and read out by MsgPracel,typically 44a34a8711Sopenharmony_ci/// used in conjunction with [`Serialize`]. 45a34a8711Sopenharmony_ci/// 46a34a8711Sopenharmony_ci/// # Example: 47a34a8711Sopenharmony_ci/// 48a34a8711Sopenharmony_ci/// ```rust 49a34a8711Sopenharmony_ci/// use ipc::parcel::{Deserialize, MsgParcel}; 50a34a8711Sopenharmony_ci/// use ipc::IpcResult; 51a34a8711Sopenharmony_ci/// 52a34a8711Sopenharmony_ci/// struct Foo { 53a34a8711Sopenharmony_ci/// a: Vec<i32>, 54a34a8711Sopenharmony_ci/// b: String, 55a34a8711Sopenharmony_ci/// } 56a34a8711Sopenharmony_ci/// 57a34a8711Sopenharmony_ci/// impl Deserialize for Foo { 58a34a8711Sopenharmony_ci/// fn deserialize(parcel: &mut MsgParcel) -> IpcResult<Self> { 59a34a8711Sopenharmony_ci/// let a = parcel.read()?; 60a34a8711Sopenharmony_ci/// let b = parcel.read()?; 61a34a8711Sopenharmony_ci/// Ok(Self { a, b }) 62a34a8711Sopenharmony_ci/// } 63a34a8711Sopenharmony_ci/// } 64a34a8711Sopenharmony_ci/// ``` 65a34a8711Sopenharmony_cipub trait Deserialize: Sized { 66a34a8711Sopenharmony_ci /// Deserialize and read out from MsgParcel. 67a34a8711Sopenharmony_ci fn deserialize(parcel: &mut MsgParcel) -> IpcResult<Self>; 68a34a8711Sopenharmony_ci} 69a34a8711Sopenharmony_ci 70a34a8711Sopenharmony_cipub const NULL_FLAG: i32 = 0; 71a34a8711Sopenharmony_cipub const NON_NULL_FLAG: i32 = 1; 72a34a8711Sopenharmony_ci 73a34a8711Sopenharmony_ciimpl<T: Serialize> Serialize for Option<T> { 74a34a8711Sopenharmony_ci fn serialize(&self, parcel: &mut MsgParcel) -> IpcResult<()> { 75a34a8711Sopenharmony_ci if let Some(inner) = self { 76a34a8711Sopenharmony_ci parcel.write(&NON_NULL_FLAG)?; 77a34a8711Sopenharmony_ci parcel.write(inner) 78a34a8711Sopenharmony_ci } else { 79a34a8711Sopenharmony_ci parcel.write(&NULL_FLAG) 80a34a8711Sopenharmony_ci } 81a34a8711Sopenharmony_ci } 82a34a8711Sopenharmony_ci} 83a34a8711Sopenharmony_ci 84a34a8711Sopenharmony_ciimpl<T: Deserialize> Deserialize for Option<T> { 85a34a8711Sopenharmony_ci fn deserialize(parcel: &mut MsgParcel) -> IpcResult<Self> { 86a34a8711Sopenharmony_ci let null: i32 = parcel.read()?; 87a34a8711Sopenharmony_ci if null == NULL_FLAG { 88a34a8711Sopenharmony_ci Ok(None) 89a34a8711Sopenharmony_ci } else { 90a34a8711Sopenharmony_ci parcel.read().map(Some) 91a34a8711Sopenharmony_ci } 92a34a8711Sopenharmony_ci } 93a34a8711Sopenharmony_ci} 94a34a8711Sopenharmony_ci 95a34a8711Sopenharmony_ci#[cfg(test)] 96a34a8711Sopenharmony_cimod test { 97a34a8711Sopenharmony_ci use super::{Deserialize, Serialize}; 98a34a8711Sopenharmony_ci use crate::parcel::MsgParcel; 99a34a8711Sopenharmony_ci #[derive(PartialEq, Eq, Debug)] 100a34a8711Sopenharmony_ci struct TestStruct { 101a34a8711Sopenharmony_ci a: bool, 102a34a8711Sopenharmony_ci b: i8, 103a34a8711Sopenharmony_ci c: String, 104a34a8711Sopenharmony_ci } 105a34a8711Sopenharmony_ci 106a34a8711Sopenharmony_ci /// UT test cases for `Serialize` 107a34a8711Sopenharmony_ci /// 108a34a8711Sopenharmony_ci /// # Brief 109a34a8711Sopenharmony_ci /// 1. Impl Serialize for a type. 110a34a8711Sopenharmony_ci /// 2. Write this type to the MsgParcel and then read it out, check the 111a34a8711Sopenharmony_ci /// correctness. 112a34a8711Sopenharmony_ci #[test] 113a34a8711Sopenharmony_ci fn serialize_test() { 114a34a8711Sopenharmony_ci impl Serialize for TestStruct { 115a34a8711Sopenharmony_ci fn serialize(&self, parcel: &mut crate::parcel::MsgParcel) -> crate::IpcResult<()> { 116a34a8711Sopenharmony_ci parcel.write(&self.a).unwrap(); 117a34a8711Sopenharmony_ci parcel.write(&self.c).unwrap(); 118a34a8711Sopenharmony_ci Ok(()) 119a34a8711Sopenharmony_ci } 120a34a8711Sopenharmony_ci } 121a34a8711Sopenharmony_ci let mut msg = MsgParcel::new(); 122a34a8711Sopenharmony_ci let test = TestStruct { 123a34a8711Sopenharmony_ci a: true, 124a34a8711Sopenharmony_ci b: 0, 125a34a8711Sopenharmony_ci c: String::from("hello"), 126a34a8711Sopenharmony_ci }; 127a34a8711Sopenharmony_ci msg.write(&test).unwrap(); 128a34a8711Sopenharmony_ci assert!(msg.read::<bool>().unwrap()); 129a34a8711Sopenharmony_ci assert_eq!(String::from("hello"), msg.read::<String>().unwrap()); 130a34a8711Sopenharmony_ci } 131a34a8711Sopenharmony_ci 132a34a8711Sopenharmony_ci /// UT test cases for `Deserialize` 133a34a8711Sopenharmony_ci /// 134a34a8711Sopenharmony_ci /// # Brief 135a34a8711Sopenharmony_ci /// 1. Impl Deserialize for a type. 136a34a8711Sopenharmony_ci /// 2. Write this type to the MsgParcel and then read it out, check the 137a34a8711Sopenharmony_ci /// correctness. 138a34a8711Sopenharmony_ci #[test] 139a34a8711Sopenharmony_ci fn deserialize_test() { 140a34a8711Sopenharmony_ci impl Deserialize for TestStruct { 141a34a8711Sopenharmony_ci fn deserialize(parcel: &mut MsgParcel) -> crate::IpcResult<Self> { 142a34a8711Sopenharmony_ci let a = parcel.read().unwrap(); 143a34a8711Sopenharmony_ci let b = parcel.read().unwrap(); 144a34a8711Sopenharmony_ci let c = parcel.read().unwrap(); 145a34a8711Sopenharmony_ci Ok(Self { a, b, c }) 146a34a8711Sopenharmony_ci } 147a34a8711Sopenharmony_ci } 148a34a8711Sopenharmony_ci let mut msg = MsgParcel::new(); 149a34a8711Sopenharmony_ci let test = TestStruct { 150a34a8711Sopenharmony_ci a: true, 151a34a8711Sopenharmony_ci b: 0, 152a34a8711Sopenharmony_ci c: String::from("hello"), 153a34a8711Sopenharmony_ci }; 154a34a8711Sopenharmony_ci msg.write(&test.a).unwrap(); 155a34a8711Sopenharmony_ci msg.write(&test.b).unwrap(); 156a34a8711Sopenharmony_ci msg.write(&test.c).unwrap(); 157a34a8711Sopenharmony_ci assert_eq!(test, msg.read().unwrap()); 158a34a8711Sopenharmony_ci } 159a34a8711Sopenharmony_ci} 160