Skip to main content

fory_core/serializer/
core.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::context::{ReadContext, WriteContext};
19use crate::error::Error;
20use crate::meta::FieldInfo;
21use crate::resolver::{RefFlag, RefMode, TypeInfo, TypeResolver};
22use crate::serializer::struct_;
23use crate::type_id::{self, TypeId};
24use std::any::Any;
25use std::rc::Rc;
26use std::sync::Arc;
27
28#[cold]
29#[inline(never)]
30fn default_unavailable<S: Serializer>() -> Result<S::Target, Error> {
31    Err(Error::type_error(format!(
32        "serializer {} has no default for target {}",
33        std::any::type_name::<S>(),
34        std::any::type_name::<S::Target>(),
35    )))
36}
37
38/// Static serialization behavior for one runtime [`Serializer::Target`].
39///
40/// Implementations define type-level serialization behavior and are never
41/// instantiated by Fory. Ordinary local types use `Target = Self`.
42pub trait Serializer: Sized + 'static {
43    type Target: Sized + 'static;
44
45    /// Write the target body only.
46    fn write_data(value: &Self::Target, context: &mut WriteContext) -> Result<(), Error>;
47
48    /// Read the target body only.
49    fn read_data(context: &mut ReadContext) -> Result<Self::Target, Error>;
50
51    /// Construct a target for a null or missing local value.
52    #[inline(always)]
53    fn default_value(context: &mut ReadContext) -> Result<Self::Target, Error> {
54        let _ = context;
55        default_unavailable::<Self>()
56    }
57
58    /// Write a complete value, including the requested reference and type
59    /// information envelopes, then write its body.
60    #[doc(hidden)]
61    #[inline(always)]
62    fn write(
63        value: &Self::Target,
64        context: &mut WriteContext,
65        ref_mode: RefMode,
66        write_type_info: bool,
67    ) -> Result<(), Error> {
68        if ref_mode != RefMode::None {
69            context.writer.write_i8(RefFlag::NotNullValue as i8);
70        }
71        if write_type_info {
72            Self::write_type_info(context)?;
73        }
74        Self::write_data(value, context)
75    }
76
77    /// Resolve and emit metadata for one dynamically selected concrete target.
78    ///
79    /// Homogeneous collection and map owners retain the returned [`TypeInfo`]
80    /// and pass it to every body in that wire chunk.
81    #[doc(hidden)]
82    #[inline(always)]
83    fn write_type_info_value(
84        context: &mut WriteContext,
85        target_type_id: std::any::TypeId,
86    ) -> Result<Rc<TypeInfo>, Error> {
87        context.write_target_type_info(Self::static_type_id() as u32, target_type_id)
88    }
89
90    /// Write a value using concrete type metadata already emitted by its
91    /// containing collection or map owner.
92    #[doc(hidden)]
93    #[inline(always)]
94    fn write_with_type_info(
95        value: &Self::Target,
96        context: &mut WriteContext,
97        ref_mode: RefMode,
98        type_info: &Rc<TypeInfo>,
99    ) -> Result<(), Error> {
100        let _ = type_info;
101        Self::write(value, context, ref_mode, false)
102    }
103
104    /// Read a complete value, including the requested reference and type
105    /// information envelopes, then read its body.
106    #[doc(hidden)]
107    #[inline(always)]
108    fn read(
109        context: &mut ReadContext,
110        ref_mode: RefMode,
111        read_type_info: bool,
112    ) -> Result<Self::Target, Error> {
113        if ref_mode != RefMode::None {
114            let flag = context.reader.read_i8()?;
115            if flag == RefFlag::Null as i8 {
116                return Self::default_value(context);
117            }
118        }
119        if read_type_info {
120            Self::read_type_info(context)?;
121        }
122        Self::read_data(context)
123    }
124
125    #[doc(hidden)]
126    #[inline(always)]
127    fn read_with_type_info(
128        context: &mut ReadContext,
129        ref_mode: RefMode,
130        type_info: &Rc<TypeInfo>,
131    ) -> Result<Self::Target, Error> {
132        let _ = type_info;
133        Self::read(context, ref_mode, false)
134    }
135
136    #[doc(hidden)]
137    #[inline(always)]
138    fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
139        context.write_provider_type_info(
140            Self::static_type_id() as u32,
141            std::any::TypeId::of::<Self>(),
142        )?;
143        Ok(())
144    }
145
146    #[doc(hidden)]
147    #[inline(always)]
148    fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
149        if Self::IS_POLYMORPHIC {
150            context.read_any_type_info()?;
151        } else {
152            context.read_type_info_for(Self::metadata_target_type_id())?;
153        }
154        Ok(())
155    }
156
157    /// Read directly into the final owner for sync dynamic carriers.
158    #[cold]
159    #[inline(never)]
160    fn read_arc_any(context: &mut ReadContext) -> Result<Arc<dyn Any + Send + Sync>, Error> {
161        let _ = context;
162        Err(Error::type_error(format!(
163            "target {} cannot be represented as Arc<dyn Any + Send + Sync>",
164            std::any::type_name::<Self::Target>(),
165        )))
166    }
167
168    #[doc(hidden)]
169    #[inline(always)]
170    fn static_type_id() -> TypeId {
171        TypeId::EXT
172    }
173
174    #[doc(hidden)]
175    #[inline(always)]
176    fn reserved_space() -> usize {
177        std::mem::size_of::<Self::Target>()
178    }
179
180    #[doc(hidden)]
181    const IS_OPTIONAL: bool = false;
182
183    #[doc(hidden)]
184    const IS_POLYMORPHIC: bool = false;
185
186    #[doc(hidden)]
187    const IS_SHARED_REF: bool = false;
188
189    #[doc(hidden)]
190    const IS_WRAPPER: bool = Self::IS_SHARED_REF;
191
192    #[doc(hidden)]
193    const REQUIRES_SCOPED_ACCESS: bool = false;
194
195    /// Return the concrete registered owner represented by this serializer's wire metadata.
196    #[doc(hidden)]
197    #[inline(always)]
198    fn metadata_target_type_id() -> std::any::TypeId {
199        std::any::TypeId::of::<Self::Target>()
200    }
201
202    /// Whether every successful `read_data` call consumes at least one input byte.
203    ///
204    /// Custom serializers are conservative by default. Implementations may opt in
205    /// only when this property holds for every value they can read.
206    #[doc(hidden)]
207    const READ_DATA_ALWAYS_ADVANCES: bool = false;
208
209    #[doc(hidden)]
210    #[inline(always)]
211    fn is_none(value: &Self::Target) -> bool {
212        let _ = value;
213        false
214    }
215
216    /// Return the concrete target selected by a polymorphic value.
217    ///
218    /// `None` means that the value is absent and has no concrete target.
219    #[doc(hidden)]
220    #[inline(always)]
221    fn dynamic_type_id(value: &Self::Target) -> Result<Option<std::any::TypeId>, Error> {
222        let _ = value;
223        Ok(Some(std::any::TypeId::of::<Self::Target>()))
224    }
225}
226
227#[inline(always)]
228pub(super) fn read_value_type_info<S: Serializer, const ALLOW_STRUCTURAL_META: bool>(
229    context: &mut ReadContext,
230) -> Result<Option<Rc<TypeInfo>>, Error> {
231    // Static built-in carrier headers are compact type IDs, not registered
232    // serializers. Compatible metadata and native polymorphic collection/map
233    // groups require a retained TypeInfo for their body reads; native static
234    // serializers keep their direct validated path.
235    if (context.is_compatible() || S::IS_POLYMORPHIC)
236        && !type_id::is_internal_type(S::static_type_id() as u32)
237    {
238        return read_group_type_info::<S, ALLOW_STRUCTURAL_META>(context).map(Some);
239    }
240    S::read_type_info(context)?;
241    Ok(None)
242}
243
244#[inline(always)]
245fn group_allows_structural<const ALLOW_STRUCTURAL_META: bool>(static_type_id: TypeId) -> bool {
246    ALLOW_STRUCTURAL_META && type_id::is_struct_type_id(static_type_id as u32)
247}
248
249#[inline(always)]
250pub(super) fn read_group_type_info<S: Serializer, const ALLOW_STRUCTURAL_META: bool>(
251    context: &mut ReadContext,
252) -> Result<Rc<TypeInfo>, Error> {
253    // Polymorphic serializers select the wire owner dynamically. Only Struct-compatible
254    // mapping may retain an unregistered remote schema for structural remapping; enums and
255    // extensions must bind their declared concrete owner before cache publication.
256    let static_type_id = S::static_type_id();
257    if S::IS_POLYMORPHIC {
258        context.read_any_type_info()
259    } else if group_allows_structural::<ALLOW_STRUCTURAL_META>(static_type_id) {
260        context.read_struct_type_info_for(S::metadata_target_type_id())
261    } else if type_id::is_internal_type(static_type_id as u32) && static_type_id != TypeId::UNION {
262        let type_info = context.read_any_type_info()?;
263        if type_info.get_type_id() != static_type_id {
264            return Err(Error::type_mismatch(
265                static_type_id as u32,
266                type_info.get_type_id() as u32,
267            ));
268        }
269        Ok(type_info)
270    } else {
271        context.read_type_info_for(S::metadata_target_type_id())
272    }
273}
274
275#[inline(always)]
276pub(super) fn check_group_type_info<S: Serializer, const ALLOW_STRUCTURAL_META: bool>(
277    type_info: &TypeInfo,
278) -> Result<(), Error> {
279    let static_type_id = S::static_type_id();
280    if S::IS_POLYMORPHIC {
281        return Ok(());
282    }
283    if group_allows_structural::<ALLOW_STRUCTURAL_META>(static_type_id) {
284        if !type_id::is_struct_type_id(type_info.get_type_meta_ref().get_type_id()) {
285            return Err(Error::type_error(
286                "resolved TypeInfo is not structural metadata",
287            ));
288        }
289        let resolved_target = type_info.get_harness().target_type_id();
290        if resolved_target.is_none() || resolved_target == Some(S::metadata_target_type_id()) {
291            return Ok(());
292        }
293        return Err(Error::type_error(
294            "resolved TypeInfo target does not match declared target",
295        ));
296    }
297    if type_id::is_internal_type(static_type_id as u32) && static_type_id != TypeId::UNION {
298        if type_info.get_type_id() != static_type_id {
299            return Err(Error::type_mismatch(
300                static_type_id as u32,
301                type_info.get_type_id() as u32,
302            ));
303        }
304        return Ok(());
305    }
306    if type_info.get_harness().target_type_id() != Some(S::metadata_target_type_id()) {
307        return Err(Error::type_error(
308            "resolved TypeInfo target does not match declared target",
309        ));
310    }
311    Ok(())
312}
313
314/// Schema metadata and compatible reads for derive-generated serializers.
315pub trait StructSerializer: Serializer {
316    fn type_index() -> u32;
317
318    #[cold]
319    #[inline(never)]
320    fn actual_type_id(
321        type_id: u32,
322        register_by_name: bool,
323        compatible: bool,
324        xlang: bool,
325    ) -> Result<u32, Error> {
326        let _ = xlang;
327        Ok(struct_::actual_type_id(
328            type_id,
329            register_by_name,
330            compatible,
331        ))
332    }
333
334    fn fields_info(type_resolver: &TypeResolver) -> Result<Vec<FieldInfo>, Error>;
335
336    fn variants_fields_info(
337        type_resolver: &TypeResolver,
338    ) -> Result<Vec<(String, std::any::TypeId, Vec<FieldInfo>)>, Error>;
339
340    fn sorted_field_names() -> &'static [&'static str];
341
342    fn read_compatible(
343        context: &mut ReadContext,
344        type_info: &Rc<TypeInfo>,
345    ) -> Result<Self::Target, Error>;
346
347    #[cold]
348    #[inline(never)]
349    fn read_compatible_arc_any(
350        context: &mut ReadContext,
351        type_info: &Rc<TypeInfo>,
352    ) -> Result<Arc<dyn Any + Send + Sync>, Error> {
353        let _ = context;
354        let _ = type_info;
355        Err(Error::type_error(format!(
356            "target {} cannot be represented as Arc<dyn Any + Send + Sync>",
357            std::any::type_name::<Self::Target>(),
358        )))
359    }
360}
361
362#[inline(always)]
363pub fn write_data<S: Serializer>(
364    value: &S::Target,
365    context: &mut WriteContext,
366) -> Result<(), Error> {
367    S::write_data(value, context)
368}
369
370#[inline(always)]
371pub fn read_data<S: Serializer>(context: &mut ReadContext) -> Result<S::Target, Error> {
372    S::read_data(context)
373}