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