Skip to main content

fory_core/serializer/
box_.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 super::codec::{codec_read_type_info_static, codec_ref_mode, codec_write_type_info, Codec};
19use crate::context::{ReadContext, WriteContext};
20use crate::error::Error;
21use crate::meta::FieldType;
22use crate::resolver::{RefMode, TypeInfo, TypeResolver};
23use crate::serializer::Serializer;
24use crate::type_id::TypeId;
25use std::marker::PhantomData;
26use std::rc::Rc;
27
28pub struct BoxCodec<T, C, const NULLABLE: bool, const TRACK_REF: bool>(PhantomData<(T, C)>);
29
30#[inline(always)]
31fn reserve_box<T>(context: &mut ReadContext) -> Result<(), Error> {
32    let bytes = std::mem::size_of::<T>();
33    if bytes != 0 {
34        context.reserve_graph_memory(bytes)?;
35    }
36    Ok(())
37}
38
39impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Serializer
40    for BoxCodec<T, C, NULLABLE, TRACK_REF>
41where
42    T: 'static,
43    C: Serializer<Target = T>,
44{
45    type Target = Box<T>;
46
47    #[inline(always)]
48    fn reserved_space() -> usize {
49        C::reserved_space()
50    }
51
52    #[inline(always)]
53    fn write_data(value: &Box<T>, context: &mut WriteContext) -> Result<(), Error> {
54        C::write_data(value, context)
55    }
56
57    #[inline(always)]
58    fn read_data(context: &mut ReadContext) -> Result<Box<T>, Error> {
59        reserve_box::<T>(context)?;
60        Ok(Box::new(C::read_data(context)?))
61    }
62
63    #[inline(always)]
64    fn write(
65        value: &Box<T>,
66        context: &mut WriteContext,
67        ref_mode: RefMode,
68        write_type_info: bool,
69    ) -> Result<(), Error> {
70        C::write(value, context, ref_mode, write_type_info)
71    }
72
73    #[inline(always)]
74    fn write_type_info_value(
75        context: &mut WriteContext,
76        target_type_id: std::any::TypeId,
77    ) -> Result<Rc<TypeInfo>, Error> {
78        C::write_type_info_value(context, target_type_id)
79    }
80
81    #[inline(always)]
82    fn write_with_type_info(
83        value: &Box<T>,
84        context: &mut WriteContext,
85        ref_mode: RefMode,
86        type_info: &Rc<TypeInfo>,
87    ) -> Result<(), Error> {
88        C::write_with_type_info(value, context, ref_mode, type_info)
89    }
90
91    #[inline(always)]
92    fn read(
93        context: &mut ReadContext,
94        ref_mode: RefMode,
95        read_type_info: bool,
96    ) -> Result<Box<T>, Error> {
97        reserve_box::<T>(context)?;
98        Ok(Box::new(C::read(context, ref_mode, read_type_info)?))
99    }
100
101    #[inline(always)]
102    fn read_with_type_info(
103        context: &mut ReadContext,
104        ref_mode: RefMode,
105        type_info: &Rc<TypeInfo>,
106    ) -> Result<Box<T>, Error> {
107        reserve_box::<T>(context)?;
108        Ok(Box::new(C::read_with_type_info(
109            context, ref_mode, type_info,
110        )?))
111    }
112
113    #[inline(always)]
114    fn default_value(context: &mut ReadContext) -> Result<Box<T>, Error> {
115        reserve_box::<T>(context)?;
116        Ok(Box::new(C::default_value(context)?))
117    }
118
119    #[inline(always)]
120    fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
121        C::write_type_info(context)
122    }
123
124    #[inline(always)]
125    fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
126        C::read_type_info(context)
127    }
128
129    #[inline(always)]
130    fn static_type_id() -> TypeId {
131        C::static_type_id()
132    }
133
134    const IS_OPTIONAL: bool = C::IS_OPTIONAL;
135
136    const IS_POLYMORPHIC: bool = C::IS_POLYMORPHIC;
137
138    const IS_SHARED_REF: bool = C::IS_SHARED_REF;
139
140    const IS_WRAPPER: bool = true;
141
142    const REQUIRES_SCOPED_ACCESS: bool = C::REQUIRES_SCOPED_ACCESS;
143
144    #[inline(always)]
145    fn is_none(value: &Box<T>) -> bool {
146        C::is_none(value)
147    }
148
149    #[inline(always)]
150    fn dynamic_type_id(value: &Box<T>) -> Result<Option<std::any::TypeId>, Error> {
151        C::dynamic_type_id(value)
152    }
153}
154
155impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Codec<Box<T>>
156    for BoxCodec<T, C, NULLABLE, TRACK_REF>
157where
158    T: 'static,
159    C: Codec<T>,
160{
161    #[inline(always)]
162    fn field_type(type_resolver: &TypeResolver) -> Result<FieldType, Error> {
163        let mut field_type = C::field_type(type_resolver)?;
164        field_type.nullable = NULLABLE;
165        field_type.track_ref = TRACK_REF;
166        Ok(field_type)
167    }
168
169    #[inline(always)]
170    fn field_reserved_space() -> usize {
171        C::field_reserved_space()
172    }
173
174    #[inline(always)]
175    fn write_field(value: &Box<T>, context: &mut WriteContext) -> Result<(), Error> {
176        Self::write_with_mode(
177            value,
178            context,
179            codec_ref_mode::<T, C, NULLABLE, TRACK_REF>(),
180            codec_write_type_info::<T, C>(context),
181            true,
182        )
183    }
184
185    #[inline(always)]
186    fn read_field(context: &mut ReadContext) -> Result<Box<T>, Error> {
187        <Self as Serializer>::read(
188            context,
189            codec_ref_mode::<T, C, NULLABLE, TRACK_REF>(),
190            codec_read_type_info_static::<T, C>(context),
191        )
192    }
193
194    #[inline(always)]
195    fn read_data_with_type(
196        context: &mut ReadContext,
197        remote_data_type: &FieldType,
198    ) -> Result<Box<T>, Error> {
199        reserve_box::<T>(context)?;
200        Ok(Box::new(C::read_data_with_type(context, remote_data_type)?))
201    }
202
203    #[inline(always)]
204    fn read_field_with_type(
205        context: &mut ReadContext,
206        remote_field_type: &FieldType,
207    ) -> Result<Box<T>, Error> {
208        reserve_box::<T>(context)?;
209        Ok(Box::new(C::read_field_with_type(
210            context,
211            remote_field_type,
212        )?))
213    }
214
215    #[inline(always)]
216    fn write_with_mode(
217        value: &Box<T>,
218        context: &mut WriteContext,
219        ref_mode: RefMode,
220        write_type_info: bool,
221        has_generics: bool,
222    ) -> Result<(), Error> {
223        C::write_with_mode(value, context, ref_mode, write_type_info, has_generics)
224    }
225
226    #[inline(always)]
227    fn write_with_type_info(
228        value: &Box<T>,
229        context: &mut WriteContext,
230        ref_mode: RefMode,
231        type_info: &Rc<TypeInfo>,
232        has_generics: bool,
233    ) -> Result<(), Error> {
234        <C as Codec<T>>::write_with_type_info(value, context, ref_mode, type_info, has_generics)
235    }
236
237    #[inline(always)]
238    fn read_type_info_value(
239        context: &mut ReadContext,
240    ) -> Result<super::codec::CodecReadType, Error> {
241        C::read_type_info_value(context)
242    }
243}
244
245impl_single_carrier_serializer!(BoxSerializer, Box, BoxCodec, wrapper = true);