fory_core/
fory.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::buffer::{Reader, Writer};
19use crate::config::Config;
20use crate::ensure;
21use crate::error::Error;
22use crate::resolver::context::{ContextCache, ReadContext, WriteContext};
23use crate::resolver::type_resolver::TypeResolver;
24use crate::serializer::ForyDefault;
25use crate::serializer::{Serializer, StructSerializer};
26use crate::types::config_flags::IS_NULL_FLAG;
27use crate::types::{
28    config_flags::{IS_CROSS_LANGUAGE_FLAG, IS_LITTLE_ENDIAN_FLAG},
29    Language, MAGIC_NUMBER, SIZE_OF_REF_AND_TYPE,
30};
31use std::cell::UnsafeCell;
32use std::mem;
33use std::sync::atomic::{AtomicU64, Ordering};
34use std::sync::OnceLock;
35
36/// Global counter to assign unique IDs to each Fory instance.
37static FORY_ID_COUNTER: AtomicU64 = AtomicU64::new(0);
38
39thread_local! {
40    /// Thread-local storage for WriteContext instances with fast path caching.
41    static WRITE_CONTEXTS: UnsafeCell<ContextCache<WriteContext<'static>>> =
42        UnsafeCell::new(ContextCache::new());
43
44    /// Thread-local storage for ReadContext instances with fast path caching.
45    static READ_CONTEXTS: UnsafeCell<ContextCache<ReadContext<'static>>> =
46        UnsafeCell::new(ContextCache::new());
47}
48
49/// The main Fory serialization framework instance.
50///
51/// `Fory` provides high-performance cross-language serialization and deserialization
52/// capabilities with support for multiple modes, reference tracking, and trait object serialization.
53///
54/// # Features
55///
56/// - **Cross-language serialization**: Serialize data in Rust and deserialize in other languages
57/// - **Multiple modes**: Schema-consistent and compatible serialization modes
58/// - **Reference tracking**: Handles shared and circular references
59/// - **Trait object serialization**: Supports serializing polymorphic trait objects
60/// - **Dynamic depth limiting**: Configurable limit for nested dynamic object serialization
61///
62/// # Examples
63///
64/// Basic usage:
65///
66/// ```rust, ignore
67/// use fory::Fory;
68/// use fory::ForyObject;
69///
70/// #[derive(ForyObject)]
71/// struct User {
72///     name: String,
73///     age: u32,
74/// }
75///
76/// let fory = Fory::default();
77/// let user = User { name: "Alice".to_string(), age: 30 };
78/// let bytes = fory.serialize(&user);
79/// let deserialized: User = fory.deserialize(&bytes).unwrap();
80/// ```
81///
82/// Custom configuration:
83///
84/// ```rust
85/// use fory_core::Fory;
86///
87/// let fory = Fory::default()
88///     .compatible(true)
89///     .compress_string(true)
90///     .max_dyn_depth(10);
91/// ```
92pub struct Fory {
93    /// Unique identifier for this Fory instance, used as key in thread-local context maps.
94    id: u64,
95    /// Configuration for serialization behavior.
96    config: Config,
97    type_resolver: TypeResolver,
98    /// Lazy-initialized final type resolver (thread-safe, one-time initialization).
99    final_type_resolver: OnceLock<Result<TypeResolver, Error>>,
100}
101
102impl Default for Fory {
103    fn default() -> Self {
104        Fory {
105            id: FORY_ID_COUNTER.fetch_add(1, Ordering::Relaxed),
106            config: Config::default(),
107            type_resolver: TypeResolver::default(),
108            final_type_resolver: OnceLock::new(),
109        }
110    }
111}
112
113impl Fory {
114    /// Sets the serialization compatible mode for this Fory instance.
115    ///
116    /// # Arguments
117    ///
118    /// * `compatible` - The serialization compatible mode to use. Options are:
119    ///   - `false`: Schema must be consistent between serialization and deserialization.
120    ///     No metadata is shared. This is the fastest mode.
121    ///   - true`: Supports schema evolution and type metadata sharing for better
122    ///     cross-version compatibility.
123    ///
124    /// # Returns
125    ///
126    /// Returns `self` for method chaining.
127    ///
128    /// # Note
129    ///
130    /// Setting the compatible mode also automatically configures the `share_meta` flag:
131    /// - `false` → `share_meta = false`
132    /// - true` → `share_meta = true`
133    ///
134    /// # Examples
135    ///
136    /// ```rust
137    /// use fory_core::Fory;
138    ///
139    /// let fory = Fory::default().compatible(true);
140    /// ```
141    pub fn compatible(mut self, compatible: bool) -> Self {
142        // Setting share_meta individually is not supported currently
143        self.config.share_meta = compatible;
144        self.config.compatible = compatible;
145        self.type_resolver.set_compatible(compatible);
146        if compatible {
147            self.config.check_struct_version = false;
148        }
149        self
150    }
151
152    /// Enables or disables cross-language serialization protocol.
153    ///
154    /// # Arguments
155    ///
156    /// * `xlang` - If `true`, uses the cross-language serialization format that includes
157    ///   language metadata and magic numbers for compatibility with Fory implementations
158    ///   in other languages (Java, Python, C++, etc.). If `false`, uses a Rust-only
159    ///   optimized format.
160    ///
161    /// # Returns
162    ///
163    /// Returns `self` for method chaining.
164    ///
165    /// # Default
166    ///
167    /// The default value is `false`.
168    ///
169    /// # Examples
170    ///
171    /// ```rust
172    /// use fory_core::Fory;
173    ///
174    /// // For cross-language use (default)
175    /// let fory = Fory::default().xlang(true);
176    ///
177    /// // For Rust-only optimization, this mode is faster and more compact since it avoids
178    /// // cross-language metadata and type system costs.
179    /// let fory = Fory::default().xlang(false);
180    /// ```
181    pub fn xlang(mut self, xlang: bool) -> Self {
182        self.config.xlang = xlang;
183        if !self.config.check_struct_version {
184            self.config.check_struct_version = !self.config.compatible;
185        }
186        self
187    }
188
189    /// Enables or disables meta string compression.
190    ///
191    /// # Arguments
192    ///
193    /// * `compress_string` - If `true`, enables meta string compression to reduce serialized
194    ///   payload size by deduplicating and encoding frequently used strings (such as type names
195    ///   and field names). If `false`, strings are serialized without compression.
196    ///
197    /// # Returns
198    ///
199    /// Returns `self` for method chaining.
200    ///
201    /// # Default
202    ///
203    /// The default value is `false`.
204    ///
205    /// # Trade-offs
206    ///
207    /// - **Enabled**: Smaller payload size, slightly higher CPU overhead
208    /// - **Disabled**: Larger payload size, faster serialization/deserialization
209    ///
210    /// # Examples
211    ///
212    /// ```rust
213    /// use fory_core::Fory;
214    ///
215    /// let fory = Fory::default().compress_string(true);
216    /// ```
217    pub fn compress_string(mut self, compress_string: bool) -> Self {
218        self.config.compress_string = compress_string;
219        self
220    }
221
222    /// Enables or disables class version checking for schema consistency.
223    ///
224    /// # Arguments
225    ///
226    /// * `check_struct_version` - If `true`, enables class version checking to ensure
227    ///   schema consistency between serialization and deserialization. When enabled,
228    ///   a version hash computed from field types is written/read to detect schema mismatches.
229    ///   If `false`, no version checking is performed.
230    ///
231    /// # Returns
232    ///
233    /// Returns `self` for method chaining.
234    ///
235    /// # Default
236    ///
237    /// The default value is `false`.
238    ///
239    /// # Note
240    ///
241    /// This feature is only effective when `compatible` mode is `false`. In compatible mode,
242    /// schema evolution is supported and version checking is not needed.
243    ///
244    /// # Examples
245    ///
246    /// ```rust
247    /// use fory_core::Fory;
248    ///
249    /// let fory = Fory::default()
250    ///     .compatible(false)
251    ///     .check_struct_version(true);
252    /// ```
253    pub fn check_struct_version(mut self, check_struct_version: bool) -> Self {
254        if self.config.compatible && check_struct_version {
255            // ignore setting if compatible mode is on
256            return self;
257        }
258        self.config.check_struct_version = check_struct_version;
259        self
260    }
261
262    /// Sets the maximum depth for nested dynamic object serialization.
263    ///
264    /// # Arguments
265    ///
266    /// * `max_dyn_depth` - The maximum nesting depth allowed for dynamically-typed objects
267    ///   (e.g., trait objects, boxed types). This prevents stack overflow from deeply nested
268    ///   structures in dynamic serialization scenarios.
269    ///
270    /// # Returns
271    ///
272    /// Returns `self` for method chaining.
273    ///
274    /// # Default
275    ///
276    /// The default value is `5`.
277    ///
278    /// # Behavior
279    ///
280    /// When the depth limit is exceeded during deserialization, an error is returned to prevent
281    /// potential stack overflow or infinite recursion.
282    ///
283    /// # Examples
284    ///
285    /// ```rust
286    /// use fory_core::Fory;
287    ///
288    /// // Allow deeper nesting for complex object graphs
289    /// let fory = Fory::default().max_dyn_depth(10);
290    ///
291    /// // Restrict nesting for safer deserialization
292    /// let fory = Fory::default().max_dyn_depth(3);
293    /// ```
294    pub fn max_dyn_depth(mut self, max_dyn_depth: u32) -> Self {
295        self.config.max_dyn_depth = max_dyn_depth;
296        self
297    }
298
299    /// Returns whether cross-language serialization is enabled.
300    pub fn is_xlang(&self) -> bool {
301        self.config.xlang
302    }
303
304    /// Returns the current serialization mode.
305    ///
306    /// # Returns
307    ///
308    /// `true` if the serialization mode is compatible, `false` otherwise`.
309    pub fn is_compatible(&self) -> bool {
310        self.config.compatible
311    }
312
313    /// Returns whether string compression is enabled.
314    ///
315    /// # Returns
316    ///
317    /// `true` if meta string compression is enabled, `false` otherwise.
318    pub fn is_compress_string(&self) -> bool {
319        self.config.compress_string
320    }
321
322    /// Returns whether metadata sharing is enabled.
323    ///
324    /// # Returns
325    ///
326    /// `true` if metadata sharing is enabled (automatically set based on mode), `false` otherwise.
327    pub fn is_share_meta(&self) -> bool {
328        self.config.share_meta
329    }
330
331    /// Returns the maximum depth for nested dynamic object serialization.
332    pub fn get_max_dyn_depth(&self) -> u32 {
333        self.config.max_dyn_depth
334    }
335
336    /// Returns whether class version checking is enabled.
337    ///
338    /// # Returns
339    ///
340    /// `true` if class version checking is enabled, `false` otherwise.
341    pub fn is_check_struct_version(&self) -> bool {
342        self.config.check_struct_version
343    }
344
345    /// Returns a reference to the configuration.
346    pub fn config(&self) -> &Config {
347        &self.config
348    }
349
350    /// Serializes a value of type `T` into a byte vector.
351    ///
352    /// # Type Parameters
353    ///
354    /// * `T` - The type of the value to serialize. Must implement `Serializer`.
355    ///
356    /// # Arguments
357    ///
358    /// * `record` - A reference to the value to serialize.
359    ///
360    /// # Returns
361    ///
362    /// A `Vec<u8>` containing the serialized data.
363    ///
364    /// # Examples
365    ///
366    /// ```rust, ignore
367    /// use fory::Fory;
368    /// use fory::ForyObject;
369    ///
370    /// #[derive(ForyObject)]
371    /// struct Point { x: i32, y: i32 }
372    ///
373    /// let fory = Fory::default();
374    /// let point = Point { x: 10, y: 20 };
375    /// let bytes = fory.serialize(&point);
376    /// ```
377    pub fn serialize<T: Serializer>(&self, record: &T) -> Result<Vec<u8>, Error> {
378        self.with_write_context(
379            |context| match self.serialize_with_context(record, context) {
380                Ok(_) => {
381                    let result = context.writer.dump();
382                    context.writer.reset();
383                    Ok(result)
384                }
385                Err(err) => {
386                    context.writer.reset();
387                    Err(err)
388                }
389            },
390        )
391    }
392
393    /// Serializes a value of type `T` into the provided byte buffer.
394    ///
395    /// The serialized data is appended to the end of the buffer by default.
396    /// To write from a specific position, resize the buffer before calling this method.
397    ///
398    /// # Type Parameters
399    ///
400    /// * `T` - The type of the value to serialize. Must implement `Serializer`.
401    ///
402    /// # Arguments
403    ///
404    /// * `buf` - A mutable reference to the byte buffer to append the serialized data to.
405    ///   The buffer will be resized as needed during serialization.
406    /// * `record` - A reference to the value to serialize.
407    ///
408    /// # Returns
409    ///
410    /// The number of bytes written to the buffer on success, or an error if serialization fails.
411    ///
412    /// # Notes
413    ///
414    /// - Multiple `serialize_to` calls to the same buffer will append data sequentially.
415    ///
416    /// # Examples
417    ///
418    /// Basic usage - appending to a buffer:
419    ///
420    /// ```rust, ignore
421    /// use fory_core::Fory;
422    /// use fory_derive::ForyObject;
423    ///
424    /// #[derive(ForyObject)]
425    /// struct Point {
426    ///     x: i32,
427    ///     y: i32,
428    /// }
429    ///
430    /// let fory = Fory::default();
431    /// let point = Point { x: 1, y: 2 };
432    ///
433    /// let mut buf = Vec::new();
434    /// let bytes_written = fory.serialize_to(&mut buf, &point).unwrap();
435    /// assert_eq!(bytes_written, buf.len());
436    /// ```
437    ///
438    /// Multiple serializations to the same buffer:
439    ///
440    /// ```rust, ignore
441    /// use fory_core::Fory;
442    /// use fory_derive::ForyObject;
443    ///
444    /// #[derive(ForyObject, PartialEq, Debug)]
445    /// struct Point {
446    ///     x: i32,
447    ///     y: i32,
448    /// }
449    ///
450    /// let fory = Fory::default();
451    /// let p1 = Point { x: 1, y: 2 };
452    /// let p2 = Point { x: -3, y: 4 };
453    ///
454    /// let mut buf = Vec::new();
455    ///
456    /// // First serialization
457    /// let len1 = fory.serialize_to(&mut buf, &p1).unwrap();
458    /// let offset1 = buf.len();
459    ///
460    /// // Second serialization - appends to existing data
461    /// let len2 = fory.serialize_to(&mut buf, &p2).unwrap();
462    /// let offset2 = buf.len();
463    ///
464    /// assert_eq!(offset1, len1);
465    /// assert_eq!(offset2, len1 + len2);
466    ///
467    /// // Deserialize both objects
468    /// let deserialized1: Point = fory.deserialize(&buf[0..offset1]).unwrap();
469    /// let deserialized2: Point = fory.deserialize(&buf[offset1..offset2]).unwrap();
470    /// assert_eq!(deserialized1, p1);
471    /// assert_eq!(deserialized2, p2);
472    /// ```
473    ///
474    /// Writing to a specific position using `resize`:
475    /// # Notes on `vec.resize()`
476    ///
477    /// When calling `vec.resize(n, 0)`, note that if `n` is smaller than the current length,
478    /// the buffer will be truncated (not shrunk in capacity). The capacity remains unchanged,
479    /// making subsequent writes efficient for buffer reuse patterns:
480    ///
481    /// ```rust, ignore
482    /// use fory_core::Fory;
483    /// use fory_derive::ForyObject;
484    ///
485    /// #[derive(ForyObject)]
486    /// struct Point {
487    ///     x: i32,
488    ///     y: i32,
489    /// }
490    ///
491    /// let fory = Fory::default();
492    /// let point = Point { x: 1, y: 2 };
493    ///
494    /// let mut buf = Vec::with_capacity(1024);
495    /// buf.resize(16, 0);  // Set length to 16 to append the write, capacity stays 1024
496    ///
497    /// let initial_capacity = buf.capacity();
498    /// fory.serialize_to(&mut buf, &point).unwrap();
499    ///
500    /// // Reset to smaller size to append the write - capacity unchanged
501    /// buf.resize(16, 0);
502    /// assert_eq!(buf.capacity(), initial_capacity);  // Capacity not shrunk
503    ///
504    /// // Reuse buffer efficiently without reallocation
505    /// fory.serialize_to(&mut buf, &point).unwrap();
506    /// assert_eq!(buf.capacity(), initial_capacity);  // Still no reallocation
507    /// ```
508    pub fn serialize_to<T: Serializer>(
509        &self,
510        buf: &mut Vec<u8>,
511        record: &T,
512    ) -> Result<usize, Error> {
513        let start = buf.len();
514        self.with_write_context(|context| {
515            // Context from thread-local would be 'static. but context hold the buffer through `writer` field,
516            // so we should make buffer live longer.
517            // After serializing, `detach_writer` will be called, the writer in context will be set to dangling pointer.
518            // So it's safe to make buf live to the end of this method.
519            let outlive_buffer = unsafe { mem::transmute::<&mut Vec<u8>, &mut Vec<u8>>(buf) };
520            context.attach_writer(Writer::from_buffer(outlive_buffer));
521            let result = self.serialize_with_context(record, context);
522            let written_size = context.writer.len() - start;
523            context.detach_writer();
524            match result {
525                Ok(_) => Ok(written_size),
526                Err(err) => Err(err),
527            }
528        })
529    }
530
531    /// Gets the final type resolver, building it lazily on first access.
532    #[inline(always)]
533    fn get_final_type_resolver(&self) -> Result<&TypeResolver, Error> {
534        let result = self
535            .final_type_resolver
536            .get_or_init(|| self.type_resolver.build_final_type_resolver());
537        result
538            .as_ref()
539            .map_err(|e| Error::type_error(format!("Failed to build type resolver: {}", e)))
540    }
541
542    /// Executes a closure with mutable access to a WriteContext for this Fory instance.
543    /// The context is stored in thread-local storage, eliminating all lock contention.
544    /// Uses fast path caching for O(1) access when using the same Fory instance repeatedly.
545    #[inline(always)]
546    fn with_write_context<R>(
547        &self,
548        f: impl FnOnce(&mut WriteContext) -> Result<R, Error>,
549    ) -> Result<R, Error> {
550        // SAFETY: Thread-local storage is only accessed from the current thread.
551        // We use UnsafeCell to avoid RefCell's runtime borrow checking overhead.
552        // The closure `f` does not recursively call with_write_context, so there's no aliasing.
553        WRITE_CONTEXTS.with(|cache| {
554            let cache = unsafe { &mut *cache.get() };
555            let id = self.id;
556            let config = self.config.clone();
557
558            let context = cache.get_or_insert_result(id, || {
559                // Only fetch type resolver when creating a new context
560                let type_resolver = self.get_final_type_resolver()?;
561                Ok(Box::new(WriteContext::new(type_resolver.clone(), config)))
562            })?;
563            f(context)
564        })
565    }
566
567    /// Serializes a value of type `T` into a byte vector.
568    #[inline(always)]
569    fn serialize_with_context<T: Serializer>(
570        &self,
571        record: &T,
572        context: &mut WriteContext,
573    ) -> Result<(), Error> {
574        let result = self.serialize_with_context_inner::<T>(record, context);
575        context.reset();
576        result
577    }
578
579    #[inline(always)]
580    fn serialize_with_context_inner<T: Serializer>(
581        &self,
582        record: &T,
583        context: &mut WriteContext,
584    ) -> Result<(), Error> {
585        let is_none = record.fory_is_none();
586        self.write_head::<T>(is_none, &mut context.writer);
587        let meta_start_offset = context.writer.len();
588        if !is_none {
589            if context.is_compatible() {
590                context.writer.write_i32(-1);
591            };
592            <T as Serializer>::fory_write(record, context, true, true, false)?;
593            if context.is_compatible() && !context.empty() {
594                context.write_meta(meta_start_offset);
595            }
596        }
597        Ok(())
598    }
599
600    /// Registers a struct type with a numeric type ID for serialization.
601    ///
602    /// # Type Parameters
603    ///
604    /// * `T` - The struct type to register. Must implement `StructSerializer`, `Serializer`, and `ForyDefault`.
605    ///
606    /// # Arguments
607    ///
608    /// * `id` - A unique numeric identifier for the type. This ID is used in the serialized format
609    ///   to identify the type during deserialization.
610    ///
611    /// # Panics
612    ///
613    /// May panic if the type ID conflicts with an already registered type.
614    ///
615    /// # Examples
616    ///
617    /// ```rust, ignore
618    /// use fory::Fory;
619    /// use fory::ForyObject;
620    ///
621    /// #[derive(ForyObject)]
622    /// struct User { name: String, age: u32 }
623    ///
624    /// let mut fory = Fory::default();
625    /// fory.register::<User>(100);
626    /// ```
627    pub fn register<T: 'static + StructSerializer + Serializer + ForyDefault>(
628        &mut self,
629        id: u32,
630    ) -> Result<(), Error> {
631        self.type_resolver.register_by_id::<T>(id)
632    }
633
634    /// Registers a struct type with a namespace and type name for cross-language serialization.
635    ///
636    /// # Type Parameters
637    ///
638    /// * `T` - The struct type to register. Must implement `StructSerializer`, `Serializer`, and `ForyDefault`.
639    ///
640    /// # Arguments
641    ///
642    /// * `namespace` - The namespace or package name for the type (e.g., "com.example.types").
643    ///   Use an empty string for the default namespace.
644    /// * `type_name` - The name of the type (e.g., "User").
645    ///
646    /// # Notes
647    ///
648    /// This registration method is preferred for cross-language serialization as it uses
649    /// human-readable type identifiers instead of numeric IDs, which improves compatibility
650    /// across different language implementations.
651    ///
652    /// # Examples
653    ///
654    /// ```rust, ignore
655    /// use fory::Fory;
656    /// use fory::ForyObject;
657    ///
658    /// #[derive(ForyObject)]
659    /// struct User { name: String, age: u32 }
660    ///
661    /// let mut fory = Fory::default();
662    /// fory.register_by_namespace::<User>("com.example", "User");
663    /// ```
664    pub fn register_by_namespace<T: 'static + StructSerializer + Serializer + ForyDefault>(
665        &mut self,
666        namespace: &str,
667        type_name: &str,
668    ) -> Result<(), Error> {
669        self.type_resolver
670            .register_by_namespace::<T>(namespace, type_name)
671    }
672
673    /// Registers a struct type with a type name (using the default namespace).
674    ///
675    /// # Type Parameters
676    ///
677    /// * `T` - The struct type to register. Must implement `StructSerializer`, `Serializer`, and `ForyDefault`.
678    ///
679    /// # Arguments
680    ///
681    /// * `type_name` - The name of the type (e.g., "User").
682    ///
683    /// # Notes
684    ///
685    /// This is a convenience method that calls `register_by_namespace` with an empty namespace string.
686    ///
687    /// # Examples
688    ///
689    /// ```rust, ignore
690    /// use fory::Fory;
691    /// use fory::ForyObject;
692    ///
693    /// #[derive(ForyObject)]
694    /// struct User { name: String, age: u32 }
695    ///
696    /// let mut fory = Fory::default();
697    /// fory.register_by_name::<User>("User");
698    /// ```
699    pub fn register_by_name<T: 'static + StructSerializer + Serializer + ForyDefault>(
700        &mut self,
701        type_name: &str,
702    ) -> Result<(), Error> {
703        self.register_by_namespace::<T>("", type_name)
704    }
705
706    /// Registers a custom serializer type with a numeric type ID.
707    ///
708    /// # Type Parameters
709    ///
710    /// * `T` - The type to register. Must implement `Serializer` and `ForyDefault`.
711    ///   Unlike `register()`, this does not require `StructSerializer`, making it suitable
712    ///   for non-struct types or types with custom serialization logic.
713    ///
714    /// # Arguments
715    ///
716    /// * `id` - A unique numeric identifier for the type.
717    ///
718    /// # Use Cases
719    ///
720    /// Use this method to register:
721    /// - Enum types with custom serialization
722    /// - Wrapper types
723    /// - Types with hand-written `Serializer` implementations
724    ///
725    /// # Examples
726    ///
727    /// ```rust, ignore
728    /// use fory_core::Fory;
729    ///
730    /// let mut fory = Fory::default();
731    /// fory.register_serializer::<MyCustomType>(200);
732    /// ```
733    pub fn register_serializer<T: Serializer + ForyDefault>(
734        &mut self,
735        id: u32,
736    ) -> Result<(), Error> {
737        self.type_resolver.register_serializer_by_id::<T>(id)
738    }
739
740    /// Registers a custom serializer type with a namespace and type name.
741    ///
742    /// # Type Parameters
743    ///
744    /// * `T` - The type to register. Must implement `Serializer` and `ForyDefault`.
745    ///
746    /// # Arguments
747    ///
748    /// * `namespace` - The namespace or package name for the type.
749    /// * `type_name` - The name of the type.
750    ///
751    /// # Notes
752    ///
753    /// This is the namespace-based equivalent of `register_serializer()`, preferred for
754    /// cross-language serialization scenarios.
755    ///
756    pub fn register_serializer_by_namespace<T: Serializer + ForyDefault>(
757        &mut self,
758        namespace: &str,
759        type_name: &str,
760    ) -> Result<(), Error> {
761        self.type_resolver
762            .register_serializer_by_namespace::<T>(namespace, type_name)
763    }
764
765    /// Registers a custom serializer type with a type name (using the default namespace).
766    ///
767    /// # Type Parameters
768    ///
769    /// * `T` - The type to register. Must implement `Serializer` and `ForyDefault`.
770    ///
771    /// # Arguments
772    ///
773    /// * `type_name` - The name of the type.
774    ///
775    /// # Notes
776    ///
777    /// This is a convenience method that calls `register_serializer_by_namespace` with an empty namespace.
778    pub fn register_serializer_by_name<T: Serializer + ForyDefault>(
779        &mut self,
780        type_name: &str,
781    ) -> Result<(), Error> {
782        self.register_serializer_by_namespace::<T>("", type_name)
783    }
784
785    /// Registers a generic trait object type for serialization.
786    /// This method should be used to register collection types such as `Vec<T>`, `HashMap<K, V>`, etc.
787    /// Don't register concrete struct types with this method. Use `register()` instead.
788    pub fn register_generic_trait<T: 'static + Serializer + ForyDefault>(
789        &mut self,
790    ) -> Result<(), Error> {
791        self.type_resolver.register_generic_trait::<T>()
792    }
793
794    /// Writes the serialization header to the writer.
795    #[inline(always)]
796    pub fn write_head<T: Serializer>(&self, is_none: bool, writer: &mut Writer) {
797        const HEAD_SIZE: usize = 10;
798        writer.reserve(T::fory_reserved_space() + SIZE_OF_REF_AND_TYPE + HEAD_SIZE);
799        if self.config.xlang {
800            writer.write_u16(MAGIC_NUMBER);
801        }
802        #[cfg(target_endian = "big")]
803        let mut bitmap = 0;
804        #[cfg(target_endian = "little")]
805        let mut bitmap = IS_LITTLE_ENDIAN_FLAG;
806        if self.config.xlang {
807            bitmap |= IS_CROSS_LANGUAGE_FLAG;
808        }
809        if is_none {
810            bitmap |= IS_NULL_FLAG;
811        }
812        writer.write_u8(bitmap);
813        if is_none {
814            return;
815        }
816        if self.config.xlang {
817            writer.write_u8(Language::Rust as u8);
818        }
819    }
820
821    /// Deserializes data from a byte slice into a value of type `T`.
822    ///
823    /// # Type Parameters
824    ///
825    /// * `T` - The target type to deserialize into. Must implement `Serializer` and `ForyDefault`.
826    ///
827    /// # Arguments
828    ///
829    /// * `bf` - The byte slice containing the serialized data.
830    ///
831    /// # Returns
832    ///
833    /// * `Ok(T)` - The deserialized value on success.
834    /// * `Err(Error)` - An error if deserialization fails (e.g., invalid format, type mismatch).
835    ///
836    /// # Panics
837    ///
838    /// Panics in debug mode if there are unread bytes remaining after successful deserialization,
839    /// indicating a potential protocol violation.
840    ///
841    /// # Examples
842    ///
843    /// ```rust, ignore
844    /// use fory::Fory;
845    /// use fory::ForyObject;
846    ///
847    /// #[derive(ForyObject)]
848    /// struct Point { x: i32, y: i32 }
849    ///
850    /// let fory = Fory::default();
851    /// let point = Point { x: 10, y: 20 };
852    /// let bytes = fory.serialize(&point);
853    /// let deserialized: Point = fory.deserialize(&bytes).unwrap();
854    /// ```
855    pub fn deserialize<T: Serializer + ForyDefault>(&self, bf: &[u8]) -> Result<T, Error> {
856        self.with_read_context(|context| {
857            let outlive_buffer = unsafe { mem::transmute::<&[u8], &[u8]>(bf) };
858            context.attach_reader(Reader::new(outlive_buffer));
859            let result = self.deserialize_with_context(context);
860            context.detach_reader();
861            result
862        })
863    }
864
865    /// Deserializes data from a `Reader` into a value of type `T`.
866    ///
867    /// This method is the paired read operation for [`serialize_to`](Self::serialize_to).
868    /// It reads serialized data from the current position of the reader and automatically
869    /// advances the cursor to the end of the read data, making it suitable for reading
870    /// multiple objects sequentially from the same buffer.
871    ///
872    /// # Type Parameters
873    ///
874    /// * `T` - The target type to deserialize into. Must implement `Serializer` and `ForyDefault`.
875    ///
876    /// # Arguments
877    ///
878    /// * `reader` - A mutable reference to the `Reader` containing the serialized data.
879    ///   The reader's cursor will be advanced to the end of the deserialized data.
880    ///
881    /// # Returns
882    ///
883    /// * `Ok(T)` - The deserialized value on success.
884    /// * `Err(Error)` - An error if deserialization fails (e.g., invalid format, type mismatch).
885    ///
886    /// # Notes
887    ///
888    /// - The reader's cursor is automatically updated after each successful read.
889    /// - This method is ideal for reading multiple objects from the same buffer sequentially.
890    /// - See [`serialize_to`](Self::serialize_to) for complete usage examples.
891    ///
892    /// # Examples
893    ///
894    /// Basic usage:
895    ///
896    /// ```rust, ignore
897    /// use fory_core::{Fory, Reader};
898    /// use fory_derive::ForyObject;
899    ///
900    /// #[derive(ForyObject)]
901    /// struct Point { x: i32, y: i32 }
902    ///
903    /// let fory = Fory::default();
904    /// let point = Point { x: 10, y: 20 };
905    ///
906    /// let mut buf = Vec::new();
907    /// fory.serialize_to(&point, &mut buf).unwrap();
908    ///
909    /// let mut reader = Reader::new(&buf);
910    /// let deserialized: Point = fory.deserialize_from(&mut reader).unwrap();
911    /// ```
912    pub fn deserialize_from<T: Serializer + ForyDefault>(
913        &self,
914        reader: &mut Reader,
915    ) -> Result<T, Error> {
916        self.with_read_context(|context| {
917            let outlive_buffer = unsafe { mem::transmute::<&[u8], &[u8]>(reader.bf) };
918            let mut new_reader = Reader::new(outlive_buffer);
919            new_reader.set_cursor(reader.cursor);
920            context.attach_reader(new_reader);
921            let result = self.deserialize_with_context(context);
922            let end = context.detach_reader().get_cursor();
923            reader.set_cursor(end);
924            result
925        })
926    }
927
928    /// Executes a closure with mutable access to a ReadContext for this Fory instance.
929    /// The context is stored in thread-local storage, eliminating all lock contention.
930    /// Uses fast path caching for O(1) access when using the same Fory instance repeatedly.
931    #[inline(always)]
932    fn with_read_context<R>(
933        &self,
934        f: impl FnOnce(&mut ReadContext) -> Result<R, Error>,
935    ) -> Result<R, Error> {
936        // SAFETY: Thread-local storage is only accessed from the current thread.
937        // We use UnsafeCell to avoid RefCell's runtime borrow checking overhead.
938        // The closure `f` does not recursively call with_read_context, so there's no aliasing.
939        READ_CONTEXTS.with(|cache| {
940            let cache = unsafe { &mut *cache.get() };
941            let id = self.id;
942            let config = self.config.clone();
943
944            let context = cache.get_or_insert_result(id, || {
945                // Only fetch type resolver when creating a new context
946                let type_resolver = self.get_final_type_resolver()?;
947                Ok(Box::new(ReadContext::new(type_resolver.clone(), config)))
948            })?;
949            f(context)
950        })
951    }
952
953    #[inline(always)]
954    fn deserialize_with_context<T: Serializer + ForyDefault>(
955        &self,
956        context: &mut ReadContext,
957    ) -> Result<T, Error> {
958        let result = self.deserialize_with_context_inner::<T>(context);
959        context.reset();
960        result
961    }
962
963    #[inline(always)]
964    fn deserialize_with_context_inner<T: Serializer + ForyDefault>(
965        &self,
966        context: &mut ReadContext,
967    ) -> Result<T, Error> {
968        let is_none = self.read_head(&mut context.reader)?;
969        if is_none {
970            return Ok(T::fory_default());
971        }
972        let mut bytes_to_skip = 0;
973        if context.is_compatible() {
974            let meta_offset = context.reader.read_i32()?;
975            if meta_offset != -1 {
976                bytes_to_skip = context.load_type_meta(meta_offset as usize)?;
977            }
978        }
979        let result = <T as Serializer>::fory_read(context, true, true);
980        if bytes_to_skip > 0 {
981            context.reader.skip(bytes_to_skip)?;
982        }
983        context.ref_reader.resolve_callbacks();
984        result
985    }
986
987    #[inline(always)]
988    fn read_head(&self, reader: &mut Reader) -> Result<bool, Error> {
989        if self.config.xlang {
990            let magic_numer = reader.read_u16()?;
991            ensure!(
992                magic_numer == MAGIC_NUMBER,
993                Error::invalid_data(format!(
994                    "The fory xlang serialization must start with magic number {:X}. \
995                    Please check whether the serialization is based on the xlang protocol \
996                    and the data didn't corrupt.",
997                    MAGIC_NUMBER
998                ))
999            )
1000        }
1001        let bitmap = reader.read_u8()?;
1002        let peer_is_xlang = (bitmap & IS_CROSS_LANGUAGE_FLAG) != 0;
1003        ensure!(
1004            self.config.xlang == peer_is_xlang,
1005            Error::invalid_data("header bitmap mismatch at xlang bit")
1006        );
1007        let is_little_endian = (bitmap & IS_LITTLE_ENDIAN_FLAG) != 0;
1008        ensure!(
1009            is_little_endian,
1010            Error::invalid_data(
1011                "Big endian is not supported for now, please ensure peer machine is little endian."
1012            )
1013        );
1014        let is_none = (bitmap & IS_NULL_FLAG) != 0;
1015        if is_none {
1016            return Ok(true);
1017        }
1018        if peer_is_xlang {
1019            let _peer_lang = reader.read_u8()?;
1020        }
1021        Ok(false)
1022    }
1023}