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    #[inline(always)]
135    fn metadata_target_type_id() -> std::any::TypeId {
136        C::metadata_target_type_id()
137    }
138
139    const IS_OPTIONAL: bool = C::IS_OPTIONAL;
140
141    const IS_POLYMORPHIC: bool = C::IS_POLYMORPHIC;
142
143    const IS_SHARED_REF: bool = C::IS_SHARED_REF;
144
145    const IS_WRAPPER: bool = true;
146
147    const REQUIRES_SCOPED_ACCESS: bool = C::REQUIRES_SCOPED_ACCESS;
148
149    #[inline(always)]
150    fn is_none(value: &Box<T>) -> bool {
151        C::is_none(value)
152    }
153
154    #[inline(always)]
155    fn dynamic_type_id(value: &Box<T>) -> Result<Option<std::any::TypeId>, Error> {
156        C::dynamic_type_id(value)
157    }
158}
159
160impl<T, C, const NULLABLE: bool, const TRACK_REF: bool> Codec<Box<T>>
161    for BoxCodec<T, C, NULLABLE, TRACK_REF>
162where
163    T: 'static,
164    C: Codec<T>,
165{
166    #[inline(always)]
167    fn field_type(type_resolver: &TypeResolver) -> Result<FieldType, Error> {
168        let mut field_type = C::field_type(type_resolver)?;
169        field_type.nullable = NULLABLE;
170        field_type.track_ref = TRACK_REF;
171        Ok(field_type)
172    }
173
174    #[inline(always)]
175    fn field_reserved_space() -> usize {
176        C::field_reserved_space()
177    }
178
179    #[inline(always)]
180    fn write_field(value: &Box<T>, context: &mut WriteContext) -> Result<(), Error> {
181        Self::write_with_mode(
182            value,
183            context,
184            codec_ref_mode::<T, C, NULLABLE, TRACK_REF>(),
185            codec_write_type_info::<T, C>(context),
186            true,
187        )
188    }
189
190    #[inline(always)]
191    fn read_field(context: &mut ReadContext) -> Result<Box<T>, Error> {
192        <Self as Serializer>::read(
193            context,
194            codec_ref_mode::<T, C, NULLABLE, TRACK_REF>(),
195            codec_read_type_info_static::<T, C>(context),
196        )
197    }
198
199    #[inline(always)]
200    fn read_data_with_type(
201        context: &mut ReadContext,
202        remote_data_type: &FieldType,
203    ) -> Result<Box<T>, Error> {
204        reserve_box::<T>(context)?;
205        Ok(Box::new(C::read_data_with_type(context, remote_data_type)?))
206    }
207
208    #[inline(always)]
209    fn read_field_with_type(
210        context: &mut ReadContext,
211        remote_field_type: &FieldType,
212    ) -> Result<Box<T>, Error> {
213        reserve_box::<T>(context)?;
214        Ok(Box::new(C::read_field_with_type(
215            context,
216            remote_field_type,
217        )?))
218    }
219
220    #[inline(always)]
221    fn write_with_mode(
222        value: &Box<T>,
223        context: &mut WriteContext,
224        ref_mode: RefMode,
225        write_type_info: bool,
226        has_generics: bool,
227    ) -> Result<(), Error> {
228        C::write_with_mode(value, context, ref_mode, write_type_info, has_generics)
229    }
230
231    #[inline(always)]
232    fn write_with_type_info(
233        value: &Box<T>,
234        context: &mut WriteContext,
235        ref_mode: RefMode,
236        type_info: &Rc<TypeInfo>,
237        has_generics: bool,
238    ) -> Result<(), Error> {
239        <C as Codec<T>>::write_with_type_info(value, context, ref_mode, type_info, has_generics)
240    }
241
242    #[inline(always)]
243    fn read_type_info_value(
244        context: &mut ReadContext,
245    ) -> Result<super::codec::CodecReadType, Error> {
246        C::read_type_info_value(context)
247    }
248}
249
250impl_single_carrier_serializer!(BoxSerializer, Box, BoxCodec, wrapper = true);