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