Skip to main content

fory_core/
lib.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
18//! # Fory Core
19//!
20//! This is the core implementation of the Fory serialization framework.
21//! It provides the fundamental building blocks for high-performance serialization
22//! and deserialization in Rust.
23//!
24//! ## Architecture
25//!
26//! The core library is organized into several key modules:
27//!
28//! - **`fory`**: Main serialization engine and public API
29//! - **`buffer`**: Efficient binary buffer management with Reader/Writer
30//! - **`context`**: Per-operation read/write state and context pooling types
31//! - **`row`**: Row-based serialization for zero-copy operations
32//! - **`serializer`**: Type-specific serialization implementations
33//! - **`resolver`**: Type resolution and metadata management
34//! - **`meta`**: Metadata handling for schema evolution
35//! - **`types`**: Runtime value carriers such as temporal values, decimal, Float16, BFloat16, and weak refs
36//! - **`type_id`**: Type IDs and protocol header helpers
37//! - **`error`**: Error handling and result types
38//! - **`util`**: Utility functions and helpers
39//!
40//! ## Key Concepts
41//!
42//! ### Wire Modes And Schema Evolution
43//!
44//! Fory supports two wire modes:
45//!
46//! - **Xlang mode**: the default cross-language wire format, selected with
47//!   `.xlang(true)` and compatible schema evolution when `compatible` is
48//!   omitted.
49//! - **Native mode**: the Rust-only wire format, selected with `.xlang(false)`
50//!   with compatible schema evolution when `compatible` is omitted. Add
51//!   `.compatible(false)` only when every reader and writer always uses the same
52//!   schema and you need smaller, faster payloads.
53//!
54//! ### Type System
55//!
56//! The framework uses a comprehensive type system that supports:
57//! - Primitive types (bool, integers, floats, strings)
58//! - Collections (Vec, HashMap, BTreeMap)
59//! - Optional types (`Option<T>`)
60//! - Date/time carriers with optional chrono integration
61//! - Custom structs and enums
62//! - Trait objects (Box, Rc, Arc)
63//!
64//! ### Performance Optimizations
65//!
66//! - **Zero-copy deserialization** in row mode
67//! - **Buffer pre-allocation** to minimize allocations
68//! - **Variable-length encoding** for compact representation
69//! - **Little-endian byte order** for cross-platform compatibility
70//!
71//! ### Trait Object Serialization
72//!
73//! Fory supports polymorphic serialization through trait objects:
74//!
75//! #### Box-Based Trait Objects
76//!
77//! Define custom traits and register implementations:
78//!
79//! ```rust,ignore
80//! use fory_core::{Fory, register_trait_type, Serializer};
81//! use fory_derive::{ForyEnum, ForyStruct, ForyUnion};
82//!
83//! trait Animal: Serializer {
84//!     fn speak(&self) -> String;
85//! }
86//!
87//! #[derive(ForyStruct, Debug)]
88//! struct Dog { name: String }
89//!
90//! #[derive(ForyStruct, Debug)]
91//! struct Cat { name: String }
92//!
93//! impl Animal for Dog {
94//!     fn speak(&self) -> String { "Woof!".to_string() }
95//! }
96//!
97//! impl Animal for Cat {
98//!     fn speak(&self) -> String { "Meow!".to_string() }
99//! }
100//!
101//! register_trait_type!(Animal, Dog, Cat);
102//!
103//! #[derive(ForyStruct)]
104//! struct Zoo {
105//!     star_animal: Box<dyn Animal>,
106//! }
107//!
108//! # fn main() {
109//! let mut fory = Fory::builder().xlang(false).build();
110//! fory.register::<Dog>(100).unwrap();
111//! fory.register::<Cat>(101).unwrap();
112//! fory.register::<Zoo>(102).unwrap();
113//!
114//! let zoo = Zoo {
115//!     star_animal: Box::new(Dog { name: "Buddy".to_string() }),
116//! };
117//!
118//! let bytes = fory.serialize(&zoo).unwrap();
119//! let decoded: Zoo = fory.deserialize(&bytes).unwrap();
120//! assert_eq!(decoded.star_animal.speak(), "Woof!");
121//! # }
122//! ```
123//!
124//! #### Rc/Arc-Based Trait Objects
125//!
126//! For reference-counted trait objects, use them directly in struct fields:
127//!
128//! ```rust,ignore
129//! # use fory_core::Serializer;
130//! # use fory_derive::{ForyEnum, ForyStruct, ForyUnion};
131//! # use std::rc::Rc;
132//! # use std::sync::Arc;
133//! # trait Animal: Serializer { fn speak(&self) -> String; }
134//! #[derive(ForyStruct)]
135//! struct Shelter {
136//!     animals_rc: Vec<Rc<dyn Animal>>,
137//!     animals_arc: Vec<Arc<dyn Animal>>,
138//! }
139//! ```
140//!
141//! For standalone serialization, use auto-generated wrapper types (e.g., `AnimalRc`, `AnimalArc`)
142//! created by `register_trait_type!` due to Rust's orphan rule limitations.
143//!
144//! ## Usage
145//!
146//! This crate is typically used through the higher-level `fory` crate,
147//! which provides derive macros and a more convenient API. However,
148//! you can use the core types directly for advanced use cases.
149//!
150//! ```rust
151//! use fory_core::fory::Fory;
152//! use fory_core::error::Error;
153//! use fory_core::row::{to_row, from_row};
154//! use std::collections::HashMap;
155//!
156//! // Create a Fory instance
157//! let mut fory = Fory::builder().xlang(false).build();
158//!
159//! // Serialize String
160//! let text = String::from("Hello, Fory!");
161//! let serialized_str = fory.serialize(&text).unwrap();
162//! let deserialized_str: String = fory.deserialize(&serialized_str).unwrap();
163//! assert_eq!(text, deserialized_str);
164//!
165//! // Serialize Vec
166//! let vec_data = vec![1, 2, 3, 4, 5];
167//! let serialized_vec = fory.serialize(&vec_data).unwrap();
168//! let deserialized_vec: Vec<i32> = fory.deserialize(&serialized_vec).unwrap();
169//! assert_eq!(vec_data, deserialized_vec);
170//!
171//! // Serialize HashMap
172//! let mut map = HashMap::new();
173//! map.insert("key1".to_string(), 100);
174//! map.insert("key2".to_string(), 200);
175//! let serialized_map = fory.serialize(&map).unwrap();
176//! let deserialized_map: HashMap<String, i32> = fory.deserialize(&serialized_map).unwrap();
177//! assert_eq!(map, deserialized_map);
178//! // Register types for object serialization
179//! // fory.register::<MyStruct>(type_id);
180//!
181//! // Use row-based serialization for zero-copy operations
182//! // let row_data = to_row(&my_data);
183//! // let row = from_row::<MyStruct>(&row_data);
184//! ```
185
186// Direct lower-level derive users may resolve this crate through `::fory_core`, including
187// doctests where `crate` is the doctest crate instead of this runtime crate.
188extern crate self as fory_core;
189
190pub mod buffer;
191pub mod config;
192pub mod context;
193pub mod error;
194pub mod fory;
195pub mod meta;
196pub mod resolver;
197pub mod row;
198pub mod serializer;
199pub mod type_id;
200pub mod types;
201pub mod util;
202
203// Re-export paste for use in macros
204pub use paste;
205
206pub use crate::buffer::{Reader, Writer};
207pub use crate::config::Config;
208pub use crate::context::{ReadContext, WriteContext};
209pub use crate::error::Error;
210pub use crate::fory::{Fory, ForyBuilder};
211pub use crate::meta::{compute_field_hash, compute_struct_hash};
212pub use crate::resolver::{RefFlag, RefMode, TypeInfo, TypeResolver};
213pub use crate::serializer::{read_data, write_data, ForyDefault, Serializer, StructSerializer};
214pub use crate::type_id::TypeId;
215pub use crate::types::bfloat16::bfloat16 as BFloat16;
216pub use crate::types::float16::float16 as Float16;
217pub use crate::types::{ArcWeak, Date, Decimal, Duration, RcWeak, Timestamp, UnknownCase};