fory_core/serializer/
option.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use crate::error::Error;
19use crate::resolver::context::ReadContext;
20use crate::resolver::context::WriteContext;
21use crate::resolver::type_resolver::TypeResolver;
22use crate::serializer::{ForyDefault, Serializer};
23use crate::types::{RefFlag, TypeId};
24use std::rc::Rc;
25
26impl<T: Serializer + ForyDefault> Serializer for Option<T> {
27    #[inline(always)]
28    fn fory_write(
29        &self,
30        context: &mut WriteContext,
31        write_ref_info: bool,
32        write_type_info: bool,
33        has_generics: bool,
34    ) -> Result<(), Error> {
35        if let Some(v) = self {
36            // pass has_generics to nested collection/map serializers
37            T::fory_write(v, context, write_ref_info, write_type_info, has_generics)
38        } else {
39            if write_ref_info {
40                context.writer.write_u8(RefFlag::Null as u8);
41            }
42            // no value, skip write type info
43            Ok(())
44        }
45    }
46
47    #[inline(always)]
48    fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
49        if let Some(v) = self {
50            T::fory_write_data(v, context)
51        } else {
52            unreachable!("write should be call by serialize")
53        }
54    }
55
56    #[inline(always)]
57    fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
58        T::fory_write_type_info(context)
59    }
60
61    fn fory_read(
62        context: &mut ReadContext,
63        read_ref_info: bool,
64        read_type_info: bool,
65    ) -> Result<Self, Error>
66    where
67        Self: Sized + ForyDefault,
68    {
69        if read_ref_info {
70            let ref_flag = context.reader.read_i8()?;
71            if ref_flag == RefFlag::Null as i8 {
72                // null value won't write type info, so we can ignore `read_type_info`
73                return Ok(None);
74            }
75            if T::fory_is_shared_ref() {
76                // shared ref types always write ref flag, so we can ignore `read_type_info`
77                context.reader.move_back(1); // rewind to re-read ref flag in nested read
78                return Ok(Some(T::fory_read(context, true, read_type_info)?));
79            }
80        }
81        Ok(Some(T::fory_read(context, false, read_type_info)?))
82    }
83
84    fn fory_read_with_type_info(
85        context: &mut ReadContext,
86        read_ref_info: bool,
87        type_info: Rc<crate::TypeInfo>,
88    ) -> Result<Self, Error>
89    where
90        Self: Sized + ForyDefault,
91    {
92        if read_ref_info {
93            let ref_flag = context.reader.read_i8()?;
94            if ref_flag == RefFlag::Null as i8 {
95                return Ok(None);
96            }
97        }
98        if T::fory_is_polymorphic() {
99            // Type info already resolved by caller
100            Ok(Some(T::fory_read_with_type_info(
101                context, false, type_info,
102            )?))
103        } else {
104            Ok(Some(T::fory_read_data(context)?))
105        }
106    }
107
108    #[inline(always)]
109    fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
110        if T::fory_is_polymorphic() {
111            Ok(Some(T::fory_read(context, false, true)?))
112        } else {
113            Ok(Some(T::fory_read_data(context)?))
114        }
115    }
116
117    #[inline(always)]
118    fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
119        T::fory_read_type_info(context)
120    }
121
122    #[inline(always)]
123    fn fory_reserved_space() -> usize {
124        std::mem::size_of::<T>()
125    }
126
127    #[inline(always)]
128    fn fory_get_type_id(type_resolver: &TypeResolver) -> Result<u32, Error> {
129        T::fory_get_type_id(type_resolver)
130    }
131
132    #[inline(always)]
133    fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<u32, Error> {
134        match self {
135            Some(val) => val.fory_type_id_dyn(type_resolver),
136            None => T::fory_get_type_id(type_resolver),
137        }
138    }
139
140    #[inline(always)]
141    fn fory_is_option() -> bool {
142        true
143    }
144
145    #[inline(always)]
146    fn fory_is_none(&self) -> bool {
147        self.is_none()
148    }
149
150    #[inline(always)]
151    fn fory_static_type_id() -> TypeId {
152        T::fory_static_type_id()
153    }
154
155    fn fory_is_wrapper_type() -> bool
156    where
157        Self: Sized,
158    {
159        true
160    }
161
162    #[inline(always)]
163    fn as_any(&self) -> &dyn std::any::Any {
164        self
165    }
166}
167
168impl<T: ForyDefault> ForyDefault for Option<T> {
169    #[inline(always)]
170    fn fory_default() -> Self {
171        None
172    }
173}