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