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