You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fory.apache.org by ch...@apache.org on 2025/10/11 03:08:09 UTC
(fory) branch main updated: feat(Rust): support context_pool to reduce context allocation && support se/de in multi-thread (#2737)
This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git
The following commit(s) were added to refs/heads/main by this push:
new f1187b19e feat(Rust): support context_pool to reduce context allocation && support se/de in multi-thread (#2737)
f1187b19e is described below
commit f1187b19e7648c4a3da1d817cb27452df8ad09b4
Author: urlyy <li...@gmail.com>
AuthorDate: Sat Oct 11 11:08:06 2025 +0800
feat(Rust): support context_pool to reduce context allocation && support se/de in multi-thread (#2737)
## What does this PR do?
1. Remove the lifetime annotations from `WriteContext` and `ReadContext`
because managing their lifetimes was too troublesome. The **trade-off**
is that, previously, `MetaWriterResolver` held references to the
corresponding `TypeDef` obtained from `TypeResolver`, and both contexts
also fetched references to `Harness` objects managed by `TypeResolver`.
Now, all these references have been replaced with `clone()` to simplify
lifetime management. This may introduce a non-negligible performance
overhead, but it was the only practical solution I could implement.🥲
2. Remove `&fory` from the member variables of `Context`. Instead,
`&fory` is now passed in as a function parameter rather than being
retrieved via `context.get_fory()`. This change modified many API
signatures.
3. Add two pools to `Fory`’s member variables to allow reuse of both
types of contexts. Tests confirmed that the same context addresses were
reused multiple times. However, since automatic recycling would require
`Arc<Fory>`, only manual recycling has been implemented so far — this
operation is handled internally(within `serialize()/deserialize()`), and
users don’t need to recycle contexts manually. Also, for the
`de/serialize_with_context(context)` functions, if users call them
directly, the user's manually managed contexts will **not** be returned
to the pool.
4. Add `reset()` methods to be executed on `Context objects` before
recycling.
5. Modified `TypeResolver::sorted_field_names_map` from `RefCell<...>`
to `RwLock<...>`, and changed `MetaReaderResolver::reading_type_defs`
from `Vec<Rc<TypeMeta>>` to `Vec<Arc<TypeMeta>>`. Split
`Fory::MetaStringResolver` to `ReadContext::MetaStringResolver` and
`WriteContext::MetaStringResolver`. In addition, `RefReader` was
unsafely marked as `Send` and `Sync`. These changes allow `Fory` to
support serialization across multiple threads. A concrete example can be
found in `rust/tests/tests/test_multi_thread.rs`. However, I’m not sure
whether using `Lock` and `Arc` will impact single-thread performance.
But it may be troublesome to write another `ThreadSafeFory`.
6. The reason why I `unsafe impl Send/Sync for RefReader {}`, is that ,
`RefReader` contains `Box<dyn Any>`, which by default is not
`Send`/`Sync`. But In our usage, each ref_reader is only accessed within
a context, by `one` thread at a time, so it is safe to implement
`Send`/`Sync` manually using `unsafe`.
## Related issues
- close #2717
## Does this PR introduce any user-facing change?
yes, like implementing in EXT, need to pass a extra parameter `fory`.
---
rust/benches/README.md | 22 +++
rust/fory-core/benches/simd_bench.rs | 1 -
rust/fory-core/src/buffer.rs | 101 +++++++----
rust/fory-core/src/fory.rs | 61 ++++---
rust/fory-core/src/meta/meta_string.rs | 26 ++-
rust/fory-core/src/meta/string_util.rs | 14 +-
rust/fory-core/src/meta/type_meta.rs | 36 ++--
rust/fory-core/src/resolver/context.rs | 134 +++++++++-----
rust/fory-core/src/resolver/meta_resolver.rs | 21 ++-
rust/fory-core/src/resolver/metastring_resolver.rs | 194 ++++++++++-----------
rust/fory-core/src/resolver/ref_resolver.rs | 8 +-
rust/fory-core/src/resolver/type_resolver.rs | 108 ++++++------
rust/fory-core/src/serializer/any.rs | 115 +++++++-----
rust/fory-core/src/serializer/arc.rs | 35 ++--
rust/fory-core/src/serializer/bool.rs | 16 +-
rust/fory-core/src/serializer/box_.rs | 20 ++-
rust/fory-core/src/serializer/collection.rs | 48 +++--
rust/fory-core/src/serializer/datetime.rs | 32 ++--
rust/fory-core/src/serializer/enum_.rs | 53 +++---
rust/fory-core/src/serializer/heap.rs | 16 +-
rust/fory-core/src/serializer/list.rs | 48 +++--
rust/fory-core/src/serializer/map.rs | 120 +++++++------
rust/fory-core/src/serializer/mod.rs | 94 +++++-----
rust/fory-core/src/serializer/mutex.rs | 28 +--
rust/fory-core/src/serializer/number.rs | 16 +-
rust/fory-core/src/serializer/option.rs | 20 ++-
rust/fory-core/src/serializer/rc.rs | 35 ++--
rust/fory-core/src/serializer/refcell.rs | 28 +--
rust/fory-core/src/serializer/set.rs | 32 ++--
rust/fory-core/src/serializer/skip.rs | 38 ++--
rust/fory-core/src/serializer/string.rs | 18 +-
rust/fory-core/src/serializer/struct_.rs | 66 ++++---
rust/fory-core/src/serializer/trait_object.rs | 101 ++++++-----
rust/fory-core/src/serializer/weak.rs | 66 ++++---
rust/fory-derive/src/object/derive_enum.rs | 10 +-
rust/fory-derive/src/object/misc.rs | 11 +-
rust/fory-derive/src/object/read.rs | 82 ++++-----
rust/fory-derive/src/object/serializer.rs | 16 +-
rust/fory-derive/src/object/util.rs | 52 +++---
rust/fory-derive/src/object/write.rs | 32 ++--
rust/fory/src/lib.rs | 4 +-
rust/tests/tests/compatible/test_basic_type.rs | 24 +--
rust/tests/tests/compatible/test_container.rs | 54 +++---
rust/tests/tests/compatible/test_struct_enum.rs | 42 +++--
rust/tests/tests/test_cross_language.rs | 55 +++---
rust/tests/tests/test_ext.rs | 12 +-
rust/tests/tests/test_multi_thread.rs | 102 +++++++++++
rust/tests/tests/test_ref_resolver.rs | 4 +-
48 files changed, 1341 insertions(+), 930 deletions(-)
diff --git a/rust/benches/README.md b/rust/benches/README.md
index 53108cc3a..9db37f871 100644
--- a/rust/benches/README.md
+++ b/rust/benches/README.md
@@ -4,8 +4,30 @@
cargo flamegraph --bin fory_profiler -- --operation deserialize --serializer fory
```
+detailed command:
+
+```bash
+cd benches
+rm -rf cargo-flamegraph.trace
+export CARGO_PROFILE_RELEASE_DEBUG=true &&
+cargo flamegraph \
+ --inverted \
+ --deterministic \
+ --palette rust \
+ --min-width 0.05 \
+ --bin fory_profiler -- \
+ --operation deserialize \
+ --serializer fory
+```
+
## How to run benchmarks
```bash
cargo bench
```
+
+To run only a specific benchmark group, you can use a command like
+
+```bash
+cargo bench --bench serialization_bench -- simple_struct
+```
diff --git a/rust/fory-core/benches/simd_bench.rs b/rust/fory-core/benches/simd_bench.rs
index 3f8b7daac..7fc0e422a 100644
--- a/rust/fory-core/benches/simd_bench.rs
+++ b/rust/fory-core/benches/simd_bench.rs
@@ -219,7 +219,6 @@ fn benchmark_read_utf16(c: &mut Criterion) {
for &size in &sizes {
let s = test_string.repeat(size / test_string.len() + 1);
- // 构造 UTF-16 LE 字节数据
let mut data: Vec<u8> = Vec::with_capacity(s.len() * 2);
for u in s.encode_utf16() {
let lo = (u & 0x00FF) as u8;
diff --git a/rust/fory-core/src/buffer.rs b/rust/fory-core/src/buffer.rs
index b7fefe179..ec5ea2294 100644
--- a/rust/fory-core/src/buffer.rs
+++ b/rust/fory-core/src/buffer.rs
@@ -20,6 +20,7 @@ use crate::meta::buffer_rw_string::{
write_utf8_simd,
};
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
+use std::slice;
#[derive(Default)]
pub struct Writer {
@@ -28,6 +29,11 @@ pub struct Writer {
}
impl Writer {
+ pub fn reset(&mut self) {
+ // keep capacity and reset len to 0
+ self.bf.clear();
+ }
+
pub fn dump(&self) -> Vec<u8> {
self.bf.clone()
}
@@ -304,22 +310,49 @@ impl Writer {
}
}
-pub struct Reader<'de> {
- pub(crate) bf: &'de [u8],
+pub struct Reader {
+ pub(crate) bf: *const u8,
+ len: usize,
pub(crate) cursor: usize,
}
-impl<'bf> Reader<'bf> {
- pub fn new(bf: &'bf [u8]) -> Reader<'bf> {
- Reader { bf, cursor: 0 }
+impl Reader {
+ pub fn new(bf: &[u8]) -> Reader {
+ Reader {
+ bf: bf.as_ptr(),
+ len: bf.len(),
+ cursor: 0,
+ }
+ }
+
+ pub fn init(&mut self, bf: &[u8]) {
+ self.bf = bf.as_ptr();
+ self.len = bf.len();
+ self.cursor = 0;
+ }
+
+ pub fn reset(&mut self) {
+ self.bf = std::ptr::null();
+ self.len = 0;
+ self.cursor = 0;
}
pub(crate) fn move_next(&mut self, additional: usize) {
self.cursor += additional;
}
+ #[inline]
+ unsafe fn ptr_at(&self, offset: usize) -> *const u8 {
+ self.bf.add(offset)
+ }
+
pub fn slice_after_cursor(&self) -> &[u8] {
- &self.bf[self.cursor..self.bf.len()]
+ let remaining = self.len - self.cursor;
+ if self.bf.is_null() || remaining == 0 {
+ &[]
+ } else {
+ unsafe { std::slice::from_raw_parts(self.bf.add(self.cursor), remaining) }
+ }
}
pub fn get_cursor(&self) -> usize {
@@ -327,15 +360,13 @@ impl<'bf> Reader<'bf> {
}
pub fn read_u8(&mut self) -> u8 {
- let result = self.bf[self.cursor];
+ let result = unsafe { *self.ptr_at(self.cursor) };
self.move_next(1);
result
}
pub fn read_i8(&mut self) -> i8 {
- let result = self.bf[self.cursor];
- self.move_next(1);
- result as i8
+ self.read_u8() as i8
}
pub fn read_u16(&mut self) -> u16 {
@@ -388,35 +419,35 @@ impl<'bf> Reader<'bf> {
pub fn read_varuint32(&mut self) -> u32 {
let start = self.cursor;
- let b0 = self.bf[start] as u32;
+ let b0 = unsafe { *self.bf.add(start) as u32 };
if b0 < 0x80 {
self.cursor += 1;
return b0;
}
let mut encoded = b0 & 0x7F;
- let b1 = self.bf[start + 1] as u32;
+ let b1 = unsafe { *self.bf.add(start + 1) as u32 };
encoded |= (b1 & 0x7F) << 7;
if b1 < 0x80 {
self.cursor += 2;
return encoded;
}
- let b2 = self.bf[start + 2] as u32;
+ let b2 = unsafe { *self.bf.add(start + 2) as u32 };
encoded |= (b2 & 0x7F) << 14;
if b2 < 0x80 {
self.cursor += 3;
return encoded;
}
- let b3 = self.bf[start + 3] as u32;
+ let b3 = unsafe { *self.bf.add(start + 3) as u32 };
encoded |= (b3 & 0x7F) << 21;
if b3 < 0x80 {
self.cursor += 4;
return encoded;
}
- let b4 = self.bf[start + 4] as u32;
+ let b4 = unsafe { *self.bf.add(start + 4) as u32 };
encoded |= b4 << 28;
self.cursor += 5;
encoded
@@ -429,63 +460,63 @@ impl<'bf> Reader<'bf> {
pub fn read_varuint64(&mut self) -> u64 {
let start = self.cursor;
- let b0 = self.bf[start] as u64;
+ let b0 = unsafe { *self.bf.add(start) } as u64;
if b0 < 0x80 {
self.cursor += 1;
return b0;
}
let mut var64 = b0 & 0x7F;
- let b1 = self.bf[start + 1] as u64;
+ let b1 = unsafe { *self.bf.add(start + 1) } as u64;
var64 |= (b1 & 0x7F) << 7;
if b1 < 0x80 {
self.cursor += 2;
return var64;
}
- let b2 = self.bf[start + 2] as u64;
+ let b2 = unsafe { *self.bf.add(start + 2) } as u64;
var64 |= (b2 & 0x7F) << 14;
if b2 < 0x80 {
self.cursor += 3;
return var64;
}
- let b3 = self.bf[start + 3] as u64;
+ let b3 = unsafe { *self.bf.add(start + 3) } as u64;
var64 |= (b3 & 0x7F) << 21;
if b3 < 0x80 {
self.cursor += 4;
return var64;
}
- let b4 = self.bf[start + 4] as u64;
+ let b4 = unsafe { *self.bf.add(start + 4) } as u64;
var64 |= (b4 & 0x7F) << 28;
if b4 < 0x80 {
self.cursor += 5;
return var64;
}
- let b5 = self.bf[start + 5] as u64;
+ let b5 = unsafe { *self.bf.add(start + 5) } as u64;
var64 |= (b5 & 0x7F) << 35;
if b5 < 0x80 {
self.cursor += 6;
return var64;
}
- let b6 = self.bf[start + 6] as u64;
+ let b6 = unsafe { *self.bf.add(start + 6) } as u64;
var64 |= (b6 & 0x7F) << 42;
if b6 < 0x80 {
self.cursor += 7;
return var64;
}
- let b7 = self.bf[start + 7] as u64;
+ let b7 = unsafe { *self.bf.add(start + 7) } as u64;
var64 |= (b7 & 0x7F) << 49;
if b7 < 0x80 {
self.cursor += 8;
return var64;
}
- let b8 = self.bf[start + 8] as u64;
+ let b8 = unsafe { *self.bf.add(start + 8) } as u64;
var64 |= (b8 & 0xFF) << 56;
self.cursor += 9;
var64
@@ -538,7 +569,7 @@ impl<'bf> Reader<'bf> {
// slow path
let mut result = 0u64;
let mut shift = 0;
- while self.cursor < self.bf.len() {
+ while self.cursor < self.len {
let b = self.read_u8();
result |= ((b & 0x7F) as u64) << shift;
if (b & 0x80) == 0 {
@@ -554,13 +585,17 @@ impl<'bf> Reader<'bf> {
}
pub fn get_slice(&self) -> &[u8] {
- self.bf
+ if self.bf.is_null() || self.len == 0 {
+ &[]
+ } else {
+ unsafe { slice::from_raw_parts(self.bf, self.len) }
+ }
}
- pub fn read_bytes(&mut self, len: usize) -> &'bf [u8] {
- let result = &self.bf[self.cursor..self.cursor + len];
+ pub fn read_bytes(&mut self, len: usize) -> &[u8] {
+ let s = unsafe { slice::from_raw_parts(self.bf.add(self.cursor), len) };
self.move_next(len);
- result
+ s
}
pub fn reset_cursor_to_here(&self) -> impl FnOnce(&mut Self) {
@@ -571,6 +606,12 @@ impl<'bf> Reader<'bf> {
}
pub fn aligned<T>(&self) -> bool {
- unsafe { (self.bf.as_ptr().add(self.cursor) as usize) % std::mem::align_of::<T>() == 0 }
+ if self.bf.is_null() {
+ return false;
+ }
+ unsafe { (self.bf.add(self.cursor) as usize) % std::mem::align_of::<T>() == 0 }
}
}
+
+unsafe impl Send for Reader {}
+unsafe impl Sync for Reader {}
diff --git a/rust/fory-core/src/fory.rs b/rust/fory-core/src/fory.rs
index d4d2aa891..a4c2b940b 100644
--- a/rust/fory-core/src/fory.rs
+++ b/rust/fory-core/src/fory.rs
@@ -18,9 +18,8 @@
use crate::buffer::{Reader, Writer};
use crate::ensure;
use crate::error::Error;
-use crate::resolver::context::ReadContext;
use crate::resolver::context::WriteContext;
-use crate::resolver::metastring_resolver::MetaStringResolver;
+use crate::resolver::context::{Pool, ReadContext};
use crate::resolver::type_resolver::{TypeInfo, TypeResolver};
use crate::serializer::ForyDefault;
use crate::serializer::{Serializer, StructSerializer};
@@ -31,8 +30,6 @@ use crate::types::{
};
use crate::util::get_ext_actual_type_id;
use anyhow::anyhow;
-use std::cell::RefCell;
-use std::rc::Rc;
static EMPTY_STRING: String = String::new();
@@ -84,21 +81,32 @@ pub struct Fory {
xlang: bool,
share_meta: bool,
type_resolver: TypeResolver,
- metastring_resolver: Rc<RefCell<MetaStringResolver>>,
compress_string: bool,
max_dyn_depth: u32,
+ write_context_pool: Pool<WriteContext>,
+ read_context_pool: Pool<ReadContext>,
}
impl Default for Fory {
fn default() -> Self {
+ let write_context_constructor = || {
+ let writer = Writer::default();
+ WriteContext::new(writer)
+ };
+ let read_context_constructor = || {
+ let reader = Reader::new(&[]);
+ // when context is popped out, max_dyn_depth will be assigned a valid value
+ ReadContext::new(reader, 0)
+ };
Fory {
mode: Mode::SchemaConsistent,
xlang: true,
share_meta: false,
type_resolver: TypeResolver::default(),
- metastring_resolver: Rc::from(RefCell::from(MetaStringResolver::default())),
compress_string: false,
max_dyn_depth: 5,
+ write_context_pool: Pool::new(write_context_constructor),
+ read_context_pool: Pool::new(read_context_constructor),
}
}
}
@@ -277,15 +285,6 @@ impl Fory {
&self.type_resolver
}
- /// Returns a cloned reference to the meta string resolver.
- ///
- /// # Returns
- ///
- /// An `Rc<RefCell<MetaStringResolver>>` for meta string compression and decompression.
- pub fn get_metastring_resolver(&self) -> Rc<RefCell<MetaStringResolver>> {
- Rc::clone(&self.metastring_resolver)
- }
-
pub fn write_head<T: Serializer>(&self, is_none: bool, writer: &mut Writer) {
const HEAD_SIZE: usize = 10;
writer.reserve(T::fory_reserved_space() + SIZE_OF_REF_AND_TYPE + HEAD_SIZE);
@@ -382,12 +381,14 @@ impl Fory {
/// let deserialized: Point = fory.deserialize(&bytes).unwrap();
/// ```
pub fn deserialize<T: Serializer + ForyDefault>(&self, bf: &[u8]) -> Result<T, Error> {
- let reader = Reader::new(bf);
- let mut context = ReadContext::new(self, reader, self.max_dyn_depth);
+ let mut context = self.read_context_pool.get();
+ context.init(bf, self.max_dyn_depth);
let result = self.deserialize_with_context(&mut context);
if result.is_ok() {
assert_eq!(context.reader.slice_after_cursor().len(), 0);
}
+ context.reset();
+ self.read_context_pool.put(context);
result
}
@@ -406,7 +407,7 @@ impl Fory {
bytes_to_skip = context.load_meta(meta_offset as usize);
}
}
- let result = <T as Serializer>::fory_read(context, false);
+ let result = <T as Serializer>::fory_read(self, context, false);
if bytes_to_skip > 0 {
context.reader.skip(bytes_to_skip as u32);
}
@@ -442,9 +443,11 @@ impl Fory {
/// let bytes = fory.serialize(&point);
/// ```
pub fn serialize<T: Serializer>(&self, record: &T) -> Vec<u8> {
- let mut writer = Writer::default();
- let mut context: WriteContext<'_> = WriteContext::new(self, &mut writer);
- self.serialize_with_context(record, &mut context)
+ let mut context = self.write_context_pool.get();
+ let result = self.serialize_with_context(record, &mut context);
+ context.reset();
+ self.write_context_pool.put(context);
+ result
}
pub fn serialize_with_context<T: Serializer>(
@@ -453,13 +456,13 @@ impl Fory {
context: &mut WriteContext,
) -> Vec<u8> {
let is_none = record.fory_is_none();
- self.write_head::<T>(is_none, context.writer);
+ self.write_head::<T>(is_none, &mut context.writer);
let meta_start_offset = context.writer.len();
if !is_none {
if self.mode == Mode::Compatible {
context.writer.write_i32(-1);
};
- <T as Serializer>::fory_write(record, context, false);
+ <T as Serializer>::fory_write(record, self, context, false);
if self.mode == Mode::Compatible && !context.empty() {
context.write_meta(meta_start_offset);
}
@@ -658,13 +661,19 @@ impl Fory {
}
}
-pub fn write_data<T: Serializer>(this: &T, context: &mut WriteContext, is_field: bool) {
- T::fory_write_data(this, context, is_field);
+pub fn write_data<T: Serializer>(
+ this: &T,
+ fory: &Fory,
+ context: &mut WriteContext,
+ is_field: bool,
+) {
+ T::fory_write_data(this, fory, context, is_field);
}
pub fn read_data<T: Serializer + ForyDefault>(
+ fory: &Fory,
context: &mut ReadContext,
is_field: bool,
) -> Result<T, Error> {
- T::fory_read_data(context, is_field)
+ T::fory_read_data(fory, context, is_field)
}
diff --git a/rust/fory-core/src/meta/meta_string.rs b/rust/fory-core/src/meta/meta_string.rs
index 513232fe4..9fb3d1df2 100644
--- a/rust/fory-core/src/meta/meta_string.rs
+++ b/rust/fory-core/src/meta/meta_string.rs
@@ -365,9 +365,29 @@ impl MetaStringEncoder {
}
pub fn encode_first_to_lower_special(&self, input: &str) -> Result<Vec<u8>, Error> {
- let mut chars: Vec<char> = input.chars().collect();
- chars[0] = chars[0].to_lowercase().next().unwrap();
- self.encode_generic(&chars.iter().collect::<String>(), 5)
+ if input.is_empty() {
+ return self.encode_generic("", 5);
+ }
+
+ let mut iter = input.char_indices();
+ let (first_idx, first_char) = iter.next().unwrap();
+
+ let lower = first_char.to_lowercase().to_string();
+
+ // Fast path: if lowercase has the same byte length and is ASCII,
+ // we can modify the first byte directly without rebuilding the string.
+ if lower.len() == first_char.len_utf8() && first_char.is_ascii() {
+ let mut bytes = input.as_bytes().to_owned();
+ bytes[first_idx] = lower.as_bytes()[0];
+ return self.encode_generic(std::str::from_utf8(&bytes).unwrap(), 5);
+ }
+
+ // rebuild only the necessary prefix + suffix (still efficient).
+ let (_, rest) = input.split_at(first_char.len_utf8());
+ let mut result = String::with_capacity(input.len() + lower.len() - first_char.len_utf8());
+ result.push_str(&lower);
+ result.push_str(rest);
+ self.encode_generic(&result, 5)
}
pub fn encode_all_to_lower_special(
diff --git a/rust/fory-core/src/meta/string_util.rs b/rust/fory-core/src/meta/string_util.rs
index ba77c63e0..b7ffcdd77 100644
--- a/rust/fory-core/src/meta/string_util.rs
+++ b/rust/fory-core/src/meta/string_util.rs
@@ -568,7 +568,7 @@ pub mod buffer_rw_string {
#[inline]
pub fn read_latin1_standard(reader: &mut Reader, len: usize) -> String {
- let slice = &reader.bf[reader.cursor..reader.cursor + len];
+ let slice = unsafe { std::slice::from_raw_parts(reader.bf.add(reader.cursor), len) };
let result: String = slice.iter().map(|&b| b as char).collect();
reader.move_next(len);
result
@@ -576,8 +576,8 @@ pub mod buffer_rw_string {
#[inline]
pub fn read_utf8_standard(reader: &mut Reader, len: usize) -> String {
- let result =
- String::from_utf8_lossy(&reader.bf[reader.cursor..reader.cursor + len]).to_string();
+ let slice = unsafe { std::slice::from_raw_parts(reader.bf.add(reader.cursor), len) };
+ let result = String::from_utf8_lossy(slice).to_string();
reader.move_next(len);
result
}
@@ -585,7 +585,7 @@ pub mod buffer_rw_string {
#[inline]
pub fn read_utf16_standard(reader: &mut Reader, len: usize) -> String {
assert!(len % 2 == 0, "UTF-16 length must be even");
- let slice = &reader.bf[reader.cursor..reader.cursor + len];
+ let slice = unsafe { std::slice::from_raw_parts(reader.bf.add(reader.cursor), len) };
let units: Vec<u16> = slice
.chunks(2)
// little endian
@@ -773,7 +773,7 @@ pub mod buffer_rw_string {
if len == 0 {
return String::new();
}
- let src = &reader.bf[reader.cursor..reader.cursor + len];
+ let src = unsafe { std::slice::from_raw_parts(reader.bf.add(reader.cursor), len) };
let mut out: Vec<u8> = Vec::with_capacity(len + len / 4);
@@ -873,7 +873,7 @@ pub mod buffer_rw_string {
return String::new();
}
- let src = &reader.bf[reader.cursor..reader.cursor + len];
+ let src = unsafe { std::slice::from_raw_parts(reader.bf.add(reader.cursor), len) };
let mut result = String::with_capacity(len);
unsafe {
@@ -999,7 +999,7 @@ pub mod buffer_rw_string {
String::from_utf16(&units).unwrap_or_else(|_| String::new())
}
- let slice = &reader.bf[reader.cursor..reader.cursor + len];
+ let slice = unsafe { std::slice::from_raw_parts(reader.bf.add(reader.cursor), len) };
#[cfg(target_arch = "x86_64")]
{
if std::arch::is_x86_feature_detected!("avx2") {
diff --git a/rust/fory-core/src/meta/type_meta.rs b/rust/fory-core/src/meta/type_meta.rs
index 2d0408333..2d56a2192 100644
--- a/rust/fory-core/src/meta/type_meta.rs
+++ b/rust/fory-core/src/meta/type_meta.rs
@@ -70,20 +70,16 @@ pub struct NullableFieldType {
}
impl NullableFieldType {
- pub fn from(node: FieldType) -> Self {
+ pub fn from(node: &FieldType) -> Self {
if node.type_id == TypeId::ForyNullable as u32 {
- let inner = NullableFieldType::from(node.generics.into_iter().next().unwrap());
+ let inner = NullableFieldType::from(&node.generics[0]);
NullableFieldType {
type_id: inner.type_id,
generics: inner.generics,
nullable: true,
}
} else {
- let generics = node
- .generics
- .into_iter()
- .map(NullableFieldType::from)
- .collect();
+ let generics = node.generics.iter().map(NullableFieldType::from).collect();
NullableFieldType {
type_id: node.type_id,
generics,
@@ -385,7 +381,8 @@ impl TypeMetaLayer {
Ok(writer.dump())
}
- fn sort_field_infos(field_infos: &[FieldInfo]) -> Vec<FieldInfo> {
+ fn sort_field_infos(field_infos: Vec<FieldInfo>) -> Vec<FieldInfo> {
+ let fields_len = field_infos.len();
// group
let mut primitive_fields = Vec::new();
let mut nullable_primitive_fields = Vec::new();
@@ -394,27 +391,29 @@ impl TypeMetaLayer {
let mut unknown_fields = Vec::new();
let mut collection_fields = Vec::new();
let mut map_fields = Vec::new();
- for field_info in field_infos.iter() {
+
+ for field_info in field_infos.into_iter() {
let mut type_id = field_info.field_type.type_id;
if type_id == TypeId::ForyNullable as u32 {
type_id = field_info.field_type.generics.first().unwrap().type_id;
if PRIMITIVE_TYPES.contains(&type_id) {
- nullable_primitive_fields.push(field_info.clone());
+ nullable_primitive_fields.push(field_info);
continue;
}
}
+
let internal_id = type_id & 0xff;
if PRIMITIVE_TYPES.contains(&type_id) {
- primitive_fields.push(field_info.clone());
+ primitive_fields.push(field_info);
} else if PRIMITIVE_ARRAY_TYPES.contains(&type_id)
|| FINAL_TYPES.contains(&type_id)
|| [TypeId::ENUM as u32, TypeId::NAMED_ENUM as u32].contains(&internal_id)
{
- final_fields.push(field_info.clone());
+ final_fields.push(field_info);
} else if [TypeId::LIST as u32, TypeId::SET as u32].contains(&type_id) {
- collection_fields.push(field_info.clone());
+ collection_fields.push(field_info);
} else if TypeId::MAP as u32 == type_id {
- map_fields.push(field_info.clone());
+ map_fields.push(field_info);
} else if [
TypeId::COMPATIBLE_STRUCT as u32,
TypeId::NAMED_COMPATIBLE_STRUCT as u32,
@@ -423,13 +422,14 @@ impl TypeMetaLayer {
]
.contains(&internal_id)
{
- other_fields.push(field_info.clone());
+ other_fields.push(field_info);
} else if internal_id == TypeId::UNKNOWN as u32 {
- unknown_fields.push(field_info.clone());
+ unknown_fields.push(field_info);
} else {
unreachable!("type_id: {type_id}");
}
}
+
fn sorter(a: &FieldInfo, b: &FieldInfo) -> std::cmp::Ordering {
let a_id = if a.field_type.type_id == TypeId::ForyNullable as u32 {
a.field_type.generics.first().unwrap().type_id
@@ -500,7 +500,7 @@ impl TypeMetaLayer {
unknown_fields.sort_by(sorter);
collection_fields.sort_by(sorter);
map_fields.sort_by(sorter);
- let mut sorted_field_infos = Vec::with_capacity(field_infos.len());
+ let mut sorted_field_infos = Vec::with_capacity(fields_len);
sorted_field_infos.extend(primitive_fields);
sorted_field_infos.extend(nullable_primitive_fields);
sorted_field_infos.extend(final_fields);
@@ -535,7 +535,7 @@ impl TypeMetaLayer {
for _ in 0..num_fields {
field_infos.push(FieldInfo::from_bytes(reader));
}
- let sorted_field_infos = Self::sort_field_infos(&field_infos);
+ let sorted_field_infos = Self::sort_field_infos(field_infos);
TypeMetaLayer::new(
type_id,
namespace,
diff --git a/rust/fory-core/src/resolver/context.rs b/rust/fory-core/src/resolver/context.rs
index b8415d2da..b8e031179 100644
--- a/rust/fory-core/src/resolver/context.rs
+++ b/rust/fory-core/src/resolver/context.rs
@@ -18,26 +18,28 @@
use crate::buffer::{Reader, Writer};
use crate::fory::Fory;
-use crate::meta::TypeMeta;
+use crate::meta::{MetaString, TypeMeta};
use crate::resolver::meta_resolver::{MetaReaderResolver, MetaWriterResolver};
+use crate::resolver::metastring_resolver::{
+ MetaStringBytes, MetaStringReaderResolver, MetaStringWriterResolver,
+};
use crate::resolver::ref_resolver::{RefReader, RefWriter};
use crate::resolver::type_resolver::Harness;
-use std::any::TypeId;
-use std::rc::Rc;
+use std::sync::{Arc, Mutex};
-pub struct WriteContext<'se> {
- pub writer: &'se mut Writer,
- fory: &'se Fory,
- meta_resolver: MetaWriterResolver<'se>,
+pub struct WriteContext {
+ pub writer: Writer,
+ meta_resolver: MetaWriterResolver,
+ meta_string_resolver: MetaStringWriterResolver,
pub ref_writer: RefWriter,
}
-impl<'se> WriteContext<'se> {
- pub fn new(fory: &'se Fory, writer: &'se mut Writer) -> WriteContext<'se> {
+impl WriteContext {
+ pub fn new(writer: Writer) -> WriteContext {
WriteContext {
writer,
- fory,
meta_resolver: MetaWriterResolver::default(),
+ meta_string_resolver: MetaStringWriterResolver::default(),
ref_writer: RefWriter::new(),
}
}
@@ -46,8 +48,8 @@ impl<'se> WriteContext<'se> {
self.meta_resolver.empty()
}
- pub fn push_meta(&mut self, type_id: std::any::TypeId) -> usize {
- self.meta_resolver.push(type_id, self.fory)
+ pub fn push_meta(&mut self, fory: &Fory, type_id: std::any::TypeId) -> usize {
+ self.meta_resolver.push(type_id, fory)
}
pub fn write_meta(&mut self, offset: usize) {
@@ -55,38 +57,38 @@ impl<'se> WriteContext<'se> {
offset,
&((self.writer.len() - offset - 4) as u32).to_le_bytes(),
);
- self.meta_resolver.to_bytes(self.writer).unwrap()
+ self.meta_resolver.to_bytes(&mut self.writer).unwrap()
}
- pub fn get_fory(&self) -> &Fory {
- self.fory
- }
-
- pub fn write_any_typeinfo(&mut self, concrete_type_id: TypeId) -> &'se Harness {
+ pub fn write_any_typeinfo(
+ &mut self,
+ fory: &Fory,
+ concrete_type_id: std::any::TypeId,
+ ) -> Arc<Harness> {
use crate::types::TypeId as ForyTypeId;
- let type_resolver = self.fory.get_type_resolver();
+ let type_resolver = fory.get_type_resolver();
let type_info = type_resolver.get_type_info(concrete_type_id);
let fory_type_id = type_info.get_type_id();
if type_info.is_registered_by_name() {
if fory_type_id & 0xff == ForyTypeId::NAMED_STRUCT as u32 {
self.writer.write_varuint32(fory_type_id);
- if self.fory.is_share_meta() {
- let meta_index = self.push_meta(concrete_type_id) as u32;
+ if fory.is_share_meta() {
+ let meta_index = self.push_meta(fory, concrete_type_id) as u32;
self.writer.write_varuint32(meta_index);
} else {
- type_info.get_namespace().write_to(self.writer);
- type_info.get_type_name().write_to(self.writer);
+ type_info.get_namespace().write_to(&mut self.writer);
+ type_info.get_type_name().write_to(&mut self.writer);
}
} else if fory_type_id & 0xff == ForyTypeId::NAMED_COMPATIBLE_STRUCT as u32 {
self.writer.write_varuint32(fory_type_id);
- let meta_index = self.push_meta(concrete_type_id) as u32;
+ let meta_index = self.push_meta(fory, concrete_type_id) as u32;
self.writer.write_varuint32(meta_index);
} else {
self.writer.write_varuint32(u32::MAX);
- type_info.get_namespace().write_to(self.writer);
- type_info.get_type_name().write_to(self.writer);
+ type_info.get_namespace().write_to(&mut self.writer);
+ type_info.get_type_name().write_to(&mut self.writer);
}
type_resolver
.get_name_harness(type_info.get_namespace(), type_info.get_type_name())
@@ -94,7 +96,7 @@ impl<'se> WriteContext<'se> {
} else {
if fory_type_id & 0xff == ForyTypeId::COMPATIBLE_STRUCT as u32 {
self.writer.write_varuint32(fory_type_id);
- let meta_index = self.push_meta(concrete_type_id) as u32;
+ let meta_index = self.push_meta(fory, concrete_type_id) as u32;
self.writer.write_varuint32(meta_index);
} else {
self.writer.write_varuint32(fory_type_id);
@@ -104,34 +106,47 @@ impl<'se> WriteContext<'se> {
.expect("ID harness not found")
}
}
+
+ pub fn write_meta_string_bytes(&mut self, ms: &MetaString) {
+ self.meta_string_resolver
+ .write_meta_string_bytes(&mut self.writer, ms);
+ }
+
+ pub fn reset(&mut self) {
+ self.meta_resolver.reset();
+ self.ref_writer.reset();
+ self.writer.reset();
+ }
}
-pub struct ReadContext<'de, 'bf: 'de> {
- pub reader: Reader<'bf>,
- fory: &'de Fory,
+pub struct ReadContext {
+ pub reader: Reader,
pub meta_resolver: MetaReaderResolver,
+ meta_string_resolver: MetaStringReaderResolver,
pub ref_reader: RefReader,
max_dyn_depth: u32,
current_depth: u32,
}
-impl<'de, 'bf: 'de> ReadContext<'de, 'bf> {
- pub fn new(fory: &'de Fory, reader: Reader<'bf>, max_dyn_depth: u32) -> ReadContext<'de, 'bf> {
+impl ReadContext {
+ pub fn new(reader: Reader, max_dyn_depth: u32) -> ReadContext {
ReadContext {
reader,
- fory,
meta_resolver: MetaReaderResolver::default(),
+ meta_string_resolver: MetaStringReaderResolver::default(),
ref_reader: RefReader::new(),
max_dyn_depth,
current_depth: 0,
}
}
- pub fn get_fory(&self) -> &Fory {
- self.fory
+ pub fn init(&mut self, bytes: &[u8], max_dyn_depth: u32) {
+ self.reader.init(bytes);
+ self.max_dyn_depth = max_dyn_depth;
+ self.current_depth = 0;
}
- pub fn get_meta(&self, type_index: usize) -> &Rc<TypeMeta> {
+ pub fn get_meta(&self, type_index: usize) -> &Arc<TypeMeta> {
self.meta_resolver.get(type_index)
}
@@ -141,11 +156,11 @@ impl<'de, 'bf: 'de> ReadContext<'de, 'bf> {
))
}
- pub fn read_any_typeinfo(&mut self) -> &'de Harness {
+ pub fn read_any_typeinfo(&mut self, fory: &Fory) -> Arc<Harness> {
use crate::types::TypeId as ForyTypeId;
let fory_type_id = self.reader.read_varuint32();
- let type_resolver = self.fory.get_type_resolver();
+ let type_resolver = fory.get_type_resolver();
if fory_type_id == u32::MAX {
let namespace = self.meta_resolver.read_metastring(&mut self.reader);
@@ -154,7 +169,7 @@ impl<'de, 'bf: 'de> ReadContext<'de, 'bf> {
.get_name_harness(&namespace, &type_name)
.expect("Name harness not found")
} else if fory_type_id & 0xff == ForyTypeId::NAMED_STRUCT as u32 {
- if self.fory.is_share_meta() {
+ if fory.is_share_meta() {
let _meta_index = self.reader.read_varuint32();
} else {
let namespace = self.meta_resolver.read_metastring(&mut self.reader);
@@ -180,6 +195,11 @@ impl<'de, 'bf: 'de> ReadContext<'de, 'bf> {
}
}
+ pub fn read_meta_string_bytes(&mut self) -> MetaStringBytes {
+ self.meta_string_resolver
+ .read_meta_string_bytes(&mut self.reader)
+ }
+
pub fn inc_depth(&mut self) -> Result<(), crate::error::Error> {
self.current_depth += 1;
if self.current_depth > self.max_dyn_depth {
@@ -198,4 +218,40 @@ impl<'de, 'bf: 'de> ReadContext<'de, 'bf> {
pub fn dec_depth(&mut self) {
self.current_depth = self.current_depth.saturating_sub(1);
}
+
+ pub fn reset(&mut self) {
+ self.reader.reset();
+ self.meta_resolver.reset();
+ self.ref_reader.reset();
+ }
+}
+
+pub struct Pool<T> {
+ items: Mutex<Vec<T>>,
+ factory: fn() -> T,
+}
+
+impl<T> Pool<T> {
+ pub fn new(factory: fn() -> T) -> Self {
+ Pool {
+ items: Mutex::new(vec![]),
+ factory,
+ }
+ }
+
+ pub fn get(&self) -> T {
+ let item = self
+ .items
+ .lock()
+ .unwrap()
+ .pop()
+ .unwrap_or_else(|| (self.factory)());
+ // println!("Object address: {:p}", &item);
+ item
+ }
+
+ // put back manually
+ pub fn put(&self, item: T) {
+ self.items.lock().unwrap().push(item);
+ }
}
diff --git a/rust/fory-core/src/resolver/meta_resolver.rs b/rust/fory-core/src/resolver/meta_resolver.rs
index fc13edb0e..6d12d744d 100644
--- a/rust/fory-core/src/resolver/meta_resolver.rs
+++ b/rust/fory-core/src/resolver/meta_resolver.rs
@@ -20,15 +20,15 @@ use crate::error::Error;
use crate::fory::Fory;
use crate::meta::{Encoding, MetaString, TypeMeta, NAMESPACE_DECODER};
use std::collections::HashMap;
-use std::rc::Rc;
+use std::sync::Arc;
#[derive(Default)]
pub struct MetaReaderResolver {
- pub reading_type_defs: Vec<Rc<TypeMeta>>,
+ pub reading_type_defs: Vec<Arc<TypeMeta>>,
}
impl MetaReaderResolver {
- pub fn get(&self, index: usize) -> &Rc<TypeMeta> {
+ pub fn get(&self, index: usize) -> &Arc<TypeMeta> {
unsafe { self.reading_type_defs.get_unchecked(index) }
}
@@ -37,7 +37,7 @@ impl MetaReaderResolver {
// self.reading_type_defs.reserve(meta_size as usize);
for _ in 0..meta_size {
let type_meta = TypeMeta::from_bytes(reader);
- self.reading_type_defs.push(Rc::new(type_meta));
+ self.reading_type_defs.push(Arc::new(type_meta));
}
reader.get_cursor()
}
@@ -66,17 +66,21 @@ impl MetaReaderResolver {
};
NAMESPACE_DECODER.decode(bytes, encoding).unwrap()
}
+
+ pub fn reset(&mut self) {
+ self.reading_type_defs.clear();
+ }
}
#[derive(Default)]
-pub struct MetaWriterResolver<'a> {
- type_defs: Vec<&'a Vec<u8>>,
+pub struct MetaWriterResolver {
+ type_defs: Vec<Arc<Vec<u8>>>,
type_id_index_map: HashMap<std::any::TypeId, usize>,
}
#[allow(dead_code)]
-impl<'a> MetaWriterResolver<'a> {
- pub fn push<'b: 'a>(&mut self, type_id: std::any::TypeId, fory: &'a Fory) -> usize {
+impl MetaWriterResolver {
+ pub fn push(&mut self, type_id: std::any::TypeId, fory: &Fory) -> usize {
match self.type_id_index_map.get(&type_id) {
None => {
let index = self.type_defs.len();
@@ -106,5 +110,6 @@ impl<'a> MetaWriterResolver<'a> {
pub fn reset(&mut self) {
self.type_defs.clear();
+ self.type_id_index_map.clear();
}
}
diff --git a/rust/fory-core/src/resolver/metastring_resolver.rs b/rust/fory-core/src/resolver/metastring_resolver.rs
index 71489d0ea..6e5f63cfd 100644
--- a/rust/fory-core/src/resolver/metastring_resolver.rs
+++ b/rust/fory-core/src/resolver/metastring_resolver.rs
@@ -21,7 +21,7 @@ use std::convert::TryInto;
use crate::buffer::Writer;
use crate::meta::murmurhash3_x64_128;
use crate::meta::{Encoding, MetaString};
-use crate::resolver::context::{ReadContext, WriteContext};
+use crate::Reader;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MetaStringBytes {
@@ -79,7 +79,7 @@ impl MetaStringBytes {
}
pub(crate) fn from_metastring(meta_string: &MetaString) -> Self {
- let bytes = meta_string.bytes.to_vec();
+ let mut bytes = meta_string.bytes.to_vec();
let mut hash_code = murmurhash3_x64_128(&bytes, 47).0 as i64;
hash_code = hash_code.abs();
if hash_code == 0 {
@@ -91,47 +91,33 @@ impl MetaStringBytes {
hash_code |= header;
let header = (hash_code & HEADER_MASK) as u8;
let encoding = byte_to_encoding(header);
- let mut data = bytes.clone();
- if data.len() < 16 {
- data.resize(16, 0);
+
+ if bytes.len() < 16 {
+ bytes.resize(16, 0);
}
- let first8 = u64::from_le_bytes(data[0..8].try_into().unwrap());
- let second8 = u64::from_le_bytes(data[8..16].try_into().unwrap());
+ let first8 = u64::from_le_bytes(bytes[0..8].try_into().unwrap());
+ let second8 = u64::from_le_bytes(bytes[8..16].try_into().unwrap());
+
Self::new(bytes, hash_code, encoding, first8, second8)
}
}
#[derive(Default)]
-pub struct MetaStringResolver {
- meta_string_bytes_to_string: HashMap<MetaStringBytes, String>,
-
- hash_to_meta: HashMap<i64, MetaStringBytes>,
-
- small_map: HashMap<(u64, u64, u8), MetaStringBytes>,
-
+pub struct MetaStringWriterResolver {
meta_string_to_bytes: HashMap<MetaString, MetaStringBytes>,
-
dynamic_written: Vec<Option<MetaStringBytes>>,
- dynamic_read: Vec<Option<MetaStringBytes>>,
-
dynamic_write_id: usize,
- dynamic_read_id: usize,
}
-impl MetaStringResolver {
+impl MetaStringWriterResolver {
const INITIAL_CAPACITY: usize = 8;
const SMALL_STRING_THRESHOLD: usize = 16;
pub fn new() -> Self {
- MetaStringResolver {
- meta_string_bytes_to_string: HashMap::with_capacity(Self::INITIAL_CAPACITY),
- hash_to_meta: HashMap::with_capacity(Self::INITIAL_CAPACITY),
- small_map: HashMap::with_capacity(Self::INITIAL_CAPACITY),
+ Self {
meta_string_to_bytes: HashMap::with_capacity(Self::INITIAL_CAPACITY),
dynamic_written: vec![None; 32],
- dynamic_read: vec![None; 32],
dynamic_write_id: 0,
- dynamic_read_id: 0,
}
}
@@ -139,7 +125,7 @@ impl MetaStringResolver {
if let Some(b) = self.meta_string_to_bytes.get(m) {
return b.clone();
}
- let bytes = m.bytes.clone();
+ let bytes = m.bytes.to_vec();
let hash_code = murmurhash3_x64_128(&bytes, 47).0 as i64;
let encoding = m.encoding;
let mut first8: u64 = 0;
@@ -152,7 +138,7 @@ impl MetaStringResolver {
second8 |= (bytes[8 + j] as u64) << (8 * j);
}
}
- let msb = MetaStringBytes::new(bytes.clone(), hash_code, encoding, first8, second8);
+ let msb = MetaStringBytes::new(bytes, hash_code, encoding, first8, second8);
self.meta_string_to_bytes.insert(m.clone(), msb.clone());
msb
}
@@ -160,21 +146,17 @@ impl MetaStringResolver {
pub fn write_meta_string_bytes_with_flag(&mut self, w: &mut Writer, mut mb: MetaStringBytes) {
let id = mb.dynamic_write_id;
if id == MetaStringBytes::DEFAULT_DYNAMIC_WRITE_STRING_ID {
- // allocate id
let id_usize = self.dynamic_write_id;
self.dynamic_write_id += 1;
mb.dynamic_write_id = id_usize as i16;
- // grow dynamic_written if needed
if id_usize >= self.dynamic_written.len() {
self.dynamic_written.resize(id_usize * 2, None);
}
self.dynamic_written[id_usize] = Some(mb.clone());
let len = mb.bytes.len();
- // last bit `1` indicates class is written by name instead of registered id.
let header = ((len as u32) << 2) | 0b1;
w.write_varuint32(header);
-
if len > Self::SMALL_STRING_THRESHOLD {
w.write_i64(mb.hash_code);
} else {
@@ -182,13 +164,12 @@ impl MetaStringResolver {
}
w.write_bytes(&mb.bytes);
} else {
- // write id reference: ((id + 1) << 2) | 0b11
let header = ((id as u32 + 1) << 2) | 0b11;
w.write_varuint32(header);
}
}
- pub fn write_meta_string_bytes(&mut self, context: &mut WriteContext, ms: &MetaString) {
+ pub fn write_meta_string_bytes(&mut self, writer: &mut Writer, ms: &MetaString) {
let mut mb = MetaStringBytes::from_metastring(ms);
let id = mb.dynamic_write_id;
if id == MetaStringBytes::DEFAULT_DYNAMIC_WRITE_STRING_ID {
@@ -201,34 +182,69 @@ impl MetaStringResolver {
self.dynamic_written[id_usize] = Some(mb.clone());
let len = mb.bytes.len();
- context.writer.write_varuint32((len as u32) << 1);
+ writer.write_varuint32((len as u32) << 1);
if len > Self::SMALL_STRING_THRESHOLD {
- context.writer.write_i64(mb.hash_code);
+ writer.write_i64(mb.hash_code);
} else {
- context.writer.write_u8(mb.encoding as i16 as u8);
+ writer.write_u8(mb.encoding as i16 as u8);
}
- context.writer.write_bytes(&mb.bytes);
+ writer.write_bytes(&mb.bytes);
} else {
let header = ((id as u32 + 1) << 1) | 1;
- context.writer.write_varuint32(header);
+ writer.write_varuint32(header);
+ }
+ }
+
+ pub fn reset_write(&mut self) {
+ if self.dynamic_write_id != 0 {
+ for i in 0..self.dynamic_write_id {
+ if let Some(ref mut mb) = self.dynamic_written[i] {
+ mb.dynamic_write_id = MetaStringBytes::DEFAULT_DYNAMIC_WRITE_STRING_ID;
+ }
+ self.dynamic_written[i] = None;
+ }
+ self.dynamic_write_id = 0;
+ }
+ }
+}
+
+#[derive(Default)]
+pub struct MetaStringReaderResolver {
+ meta_string_bytes_to_string: HashMap<MetaStringBytes, String>,
+ hash_to_meta: HashMap<i64, MetaStringBytes>,
+ small_map: HashMap<(u64, u64, u8), MetaStringBytes>,
+ dynamic_read: Vec<Option<MetaStringBytes>>,
+ dynamic_read_id: usize,
+}
+
+impl MetaStringReaderResolver {
+ const INITIAL_CAPACITY: usize = 8;
+ const SMALL_STRING_THRESHOLD: usize = 16;
+
+ pub fn new() -> Self {
+ Self {
+ meta_string_bytes_to_string: HashMap::with_capacity(Self::INITIAL_CAPACITY),
+ hash_to_meta: HashMap::with_capacity(Self::INITIAL_CAPACITY),
+ small_map: HashMap::with_capacity(Self::INITIAL_CAPACITY),
+ dynamic_read: vec![None; 32],
+ dynamic_read_id: 0,
}
}
pub fn read_meta_string_bytes_with_flag(
&mut self,
- context: &mut ReadContext,
+ reader: &mut Reader,
header: u32,
) -> MetaStringBytes {
let len = (header >> 2) as usize;
if (header & 0b10) == 0 {
- // by-name path
if len <= Self::SMALL_STRING_THRESHOLD {
- let mb = self.read_small_meta_string_bytes(context, len);
+ let mb = self.read_small_meta_string_bytes(reader, len);
self.update_dynamic_string(mb.clone());
mb
} else {
- let hash_code = context.reader.read_i64();
- let mb = self.read_big_meta_string_bytes(context, len, hash_code);
+ let hash_code = reader.read_i64();
+ let mb = self.read_big_meta_string_bytes(reader, len, hash_code);
self.update_dynamic_string(mb.clone());
mb
}
@@ -241,17 +257,17 @@ impl MetaStringResolver {
}
}
- pub fn read_meta_string_bytes(&mut self, context: &mut ReadContext) -> MetaStringBytes {
- let header = context.reader.read_varuint32();
+ pub fn read_meta_string_bytes(&mut self, reader: &mut Reader) -> MetaStringBytes {
+ let header = reader.read_varuint32();
let len = (header >> 1) as usize;
if (header & 0b1) == 0 {
if len > Self::SMALL_STRING_THRESHOLD {
- let hash_code = context.reader.read_i64();
- let mb = self.read_big_meta_string_bytes(context, len, hash_code);
+ let hash_code = reader.read_i64();
+ let mb = self.read_big_meta_string_bytes(reader, len, hash_code);
self.update_dynamic_string(mb.clone());
mb
} else {
- let mb = self.read_small_meta_string_bytes(context, len);
+ let mb = self.read_small_meta_string_bytes(reader, len);
self.update_dynamic_string(mb.clone());
mb
}
@@ -266,53 +282,43 @@ impl MetaStringResolver {
fn read_big_meta_string_bytes(
&mut self,
- context: &mut ReadContext,
+ reader: &mut Reader,
len: usize,
hash_code: i64,
) -> MetaStringBytes {
if let Some(existing) = self.hash_to_meta.get(&hash_code) {
- // skip bytes
- context.reader.skip(len as u32);
+ reader.skip(len as u32);
existing.clone()
} else {
- let slice = context.reader.read_bytes(len);
- let bytes = slice.to_vec();
- let mb = {
- // compute first8/second8 like createSmall
- let mut first8: u64 = 0;
- let mut second8: u64 = 0;
- for (i, b) in bytes.iter().enumerate().take(8) {
- first8 |= (*b as u64) << (8 * i);
- }
- if bytes.len() > 8 {
- for j in 0..usize::min(8, bytes.len() - 8) {
- second8 |= (bytes[8 + j] as u64) << (8 * j);
- }
+ let bytes = reader.read_bytes(len).to_vec();
+ let mut first8 = 0;
+ let mut second8 = 0;
+ for (i, b) in bytes.iter().enumerate().take(8) {
+ first8 |= (*b as u64) << (8 * i);
+ }
+ if bytes.len() > 8 {
+ for j in 0..usize::min(8, bytes.len() - 8) {
+ second8 |= (bytes[8 + j] as u64) << (8 * j);
}
- MetaStringBytes::new(bytes, hash_code, Encoding::Utf8, first8, second8)
- };
+ }
+ let mb = MetaStringBytes::new(bytes, hash_code, Encoding::Utf8, first8, second8);
self.hash_to_meta.insert(hash_code, mb.clone());
mb
}
}
- fn read_small_meta_string_bytes(
- &mut self,
- context: &mut ReadContext,
- len: usize,
- ) -> MetaStringBytes {
- let encoding_val = context.reader.read_u8();
+ fn read_small_meta_string_bytes(&mut self, reader: &mut Reader, len: usize) -> MetaStringBytes {
+ let encoding_val = reader.read_u8();
if len == 0 {
- // assert encoding is UTF-8
debug_assert_eq!(encoding_val, Encoding::Utf8 as i16 as u8);
return MetaStringBytes::EMPTY.clone();
}
let (v1, v2) = if len <= 8 {
- let v1 = Self::read_bytes_as_u64(context, len);
- (v1, 0u64)
+ let v1 = Self::read_bytes_as_u64(reader, len);
+ (v1, 0)
} else {
- let v1 = context.reader.read_i64() as u64;
- let v2 = Self::read_bytes_as_u64(context, len - 8);
+ let v1 = reader.read_i64() as u64;
+ let v2 = Self::read_bytes_as_u64(reader, len - 8);
(v1, v2)
};
let key = (v1, v2, encoding_val);
@@ -328,13 +334,12 @@ impl MetaStringResolver {
data.push(((v2 >> (8 * j)) & 0xFF) as u8);
}
}
- let mut data_trimmed = data;
- data_trimmed.truncate(len);
- let hash_code = (murmurhash3_x64_128(&data_trimmed, 47).0 as i64).abs();
+ data.truncate(len);
+ let hash_code = (murmurhash3_x64_128(&data, 47).0 as i64).abs();
let hash_code =
(hash_code as u64 & 0xffffffffffffff00_u64) as i64 | (encoding_val as i64);
let mb = MetaStringBytes::new(
- data_trimmed.clone(),
+ data.clone(),
hash_code,
byte_to_encoding(encoding_val),
v1,
@@ -345,9 +350,9 @@ impl MetaStringResolver {
}
}
- fn read_bytes_as_u64(context: &mut ReadContext, len: usize) -> u64 {
- let mut v: u64 = 0;
- let slice = context.reader.read_bytes(len);
+ fn read_bytes_as_u64(reader: &mut Reader, len: usize) -> u64 {
+ let mut v = 0;
+ let slice = reader.read_bytes(len);
for (i, b) in slice.iter().take(len).enumerate() {
v |= (*b as u64) << (8 * i);
}
@@ -363,11 +368,6 @@ impl MetaStringResolver {
self.dynamic_read[id] = Some(mb);
}
- pub fn reset(&mut self) {
- self.reset_read();
- self.reset_write();
- }
-
pub fn reset_read(&mut self) {
if self.dynamic_read_id != 0 {
for i in 0..self.dynamic_read_id {
@@ -377,20 +377,8 @@ impl MetaStringResolver {
}
}
- pub fn reset_write(&mut self) {
- if self.dynamic_write_id != 0 {
- for i in 0..self.dynamic_write_id {
- if let Some(ref mut mb) = self.dynamic_written[i] {
- mb.dynamic_write_id = MetaStringBytes::DEFAULT_DYNAMIC_WRITE_STRING_ID;
- }
- self.dynamic_written[i] = None;
- }
- self.dynamic_write_id = 0;
- }
- }
-
- pub fn read_meta_string(&mut self, context: &mut ReadContext) -> String {
- let mb = self.read_meta_string_bytes(context);
+ pub fn read_meta_string(&mut self, reader: &mut Reader) -> String {
+ let mb = self.read_meta_string_bytes(reader);
if let Some(s) = self.meta_string_bytes_to_string.get(&mb) {
s.clone()
} else {
diff --git a/rust/fory-core/src/resolver/ref_resolver.rs b/rust/fory-core/src/resolver/ref_resolver.rs
index 215b10832..77433d48b 100644
--- a/rust/fory-core/src/resolver/ref_resolver.rs
+++ b/rust/fory-core/src/resolver/ref_resolver.rs
@@ -130,7 +130,7 @@ impl RefWriter {
/// Clear all stored references.
///
/// This is useful for reusing the RefWriter for multiple serialization operations.
- pub fn clear(&mut self) {
+ pub fn reset(&mut self) {
self.refs.clear();
self.next_ref_id = 0;
}
@@ -167,6 +167,10 @@ pub struct RefReader {
callbacks: Vec<UpdateCallback>,
}
+// danger but useful for multi-thread
+unsafe impl Send for RefReader {}
+unsafe impl Sync for RefReader {}
+
impl RefReader {
/// Creates a new RefReader instance.
pub fn new() -> Self {
@@ -322,7 +326,7 @@ impl RefReader {
/// Clear all stored references and callbacks.
///
/// This is useful for reusing the RefReader for multiple deserialization operations.
- pub fn clear(&mut self) {
+ pub fn reset(&mut self) {
self.resolve_callbacks();
self.refs.clear();
self.callbacks.clear();
diff --git a/rust/fory-core/src/resolver/type_resolver.rs b/rust/fory-core/src/resolver/type_resolver.rs
index 2d17aa760..ab3c57735 100644
--- a/rust/fory-core/src/resolver/type_resolver.rs
+++ b/rust/fory-core/src/resolver/type_resolver.rs
@@ -23,17 +23,22 @@ use crate::meta::{
TYPE_NAME_ENCODINGS,
};
use crate::serializer::{ForyDefault, Serializer, StructSerializer};
-use std::cell::RefCell;
+use std::sync::{Arc, RwLock};
use std::{any::Any, collections::HashMap};
-type WriteFn = fn(&dyn Any, &mut WriteContext, is_field: bool);
-type ReadFn =
- fn(&mut ReadContext, is_field: bool, skip_ref_flag: bool) -> Result<Box<dyn Any>, Error>;
+type WriteFn = fn(&dyn Any, fory: &Fory, &mut WriteContext, is_field: bool);
+type ReadFn = fn(
+ fory: &Fory,
+ &mut ReadContext,
+ is_field: bool,
+ skip_ref_flag: bool,
+) -> Result<Box<dyn Any>, Error>;
-type WriteDataFn = fn(&dyn Any, &mut WriteContext, is_field: bool);
-type ReadDataFn = fn(&mut ReadContext, is_field: bool) -> Result<Box<dyn Any>, Error>;
+type WriteDataFn = fn(&dyn Any, fory: &Fory, &mut WriteContext, is_field: bool);
+type ReadDataFn = fn(fory: &Fory, &mut ReadContext, is_field: bool) -> Result<Box<dyn Any>, Error>;
type ToSerializerFn = fn(Box<dyn Any>) -> Result<Box<dyn Serializer>, Error>;
+#[derive(Clone)]
pub struct Harness {
write_fn: WriteFn,
read_fn: ReadFn,
@@ -82,7 +87,7 @@ impl Harness {
#[derive(Clone, Debug)]
pub struct TypeInfo {
- type_def: Vec<u8>,
+ type_def: Arc<Vec<u8>>,
type_id: u32,
namespace: MetaString,
type_name: MetaString,
@@ -104,13 +109,13 @@ impl TypeInfo {
.encode_with_encodings(type_name, TYPE_NAME_ENCODINGS)
.unwrap();
TypeInfo {
- type_def: T::fory_type_def(
+ type_def: Arc::from(T::fory_type_def(
fory,
type_id,
namespace_metastring.clone(),
type_name_metastring.clone(),
register_by_name,
- ),
+ )),
type_id,
namespace: namespace_metastring,
type_name: type_name_metastring,
@@ -140,7 +145,7 @@ impl TypeInfo {
);
let type_def = meta.to_bytes().unwrap();
TypeInfo {
- type_def,
+ type_def: Arc::from(type_def),
type_id,
namespace: namespace_metastring,
type_name: type_name_metastring,
@@ -160,8 +165,8 @@ impl TypeInfo {
&self.type_name
}
- pub fn get_type_def(&self) -> &Vec<u8> {
- &self.type_def
+ pub fn get_type_def(&self) -> Arc<Vec<u8>> {
+ self.type_def.clone()
}
pub fn is_registered_by_name(&self) -> bool {
@@ -170,14 +175,14 @@ impl TypeInfo {
}
pub struct TypeResolver {
- serializer_map: HashMap<u32, Harness>,
- name_serializer_map: HashMap<(MetaString, MetaString), Harness>,
+ serializer_map: HashMap<u32, Arc<Harness>>,
+ name_serializer_map: HashMap<(MetaString, MetaString), Arc<Harness>>,
type_id_map: HashMap<std::any::TypeId, u32>,
type_name_map: HashMap<std::any::TypeId, (MetaString, MetaString)>,
type_info_cache: HashMap<std::any::TypeId, TypeInfo>,
// Fast lookup by numeric ID for common types
type_id_index: Vec<u32>,
- sorted_field_names_map: RefCell<HashMap<std::any::TypeId, Vec<String>>>,
+ sorted_field_names_map: RwLock<HashMap<std::any::TypeId, Arc<Vec<String>>>>,
}
const NO_TYPE_ID: u32 = 1000000000;
@@ -191,7 +196,7 @@ impl Default for TypeResolver {
type_name_map: HashMap::new(),
type_info_cache: HashMap::new(),
type_id_index: Vec::new(),
- sorted_field_names_map: RefCell::new(HashMap::new()),
+ sorted_field_names_map: RwLock::new(HashMap::new()),
};
resolver.register_builtin_types();
resolver
@@ -205,7 +210,7 @@ impl TypeResolver {
macro_rules! register_basic_type {
($ty:ty, $type_id:expr) => {{
let type_info = TypeInfo {
- type_def: vec![],
+ type_def: Arc::from(vec![]),
type_id: $type_id as u32,
namespace: NAMESPACE_ENCODER
.encode_with_encodings("", NAMESPACE_ENCODINGS)
@@ -267,16 +272,17 @@ impl TypeResolver {
) {
fn write<T2: 'static + Serializer>(
this: &dyn Any,
+ fory: &Fory,
context: &mut WriteContext,
is_field: bool,
) {
let this = this.downcast_ref::<T2>();
match this {
Some(v) => {
- let skip_ref_flag =
- crate::serializer::get_skip_ref_flag::<T2>(context.get_fory());
+ let skip_ref_flag = crate::serializer::get_skip_ref_flag::<T2>(fory);
crate::serializer::write_ref_info_data(
v,
+ fory,
context,
is_field,
skip_ref_flag,
@@ -288,11 +294,13 @@ impl TypeResolver {
}
fn read<T2: 'static + Serializer + ForyDefault>(
+ fory: &Fory,
context: &mut ReadContext,
is_field: bool,
skip_ref_flag: bool,
) -> Result<Box<dyn Any>, Error> {
match crate::serializer::read_ref_info_data::<T2>(
+ fory,
context,
is_field,
skip_ref_flag,
@@ -305,23 +313,25 @@ impl TypeResolver {
fn write_data<T2: 'static + Serializer>(
this: &dyn Any,
+ fory: &Fory,
context: &mut WriteContext,
is_field: bool,
) {
let this = this.downcast_ref::<T2>();
match this {
Some(v) => {
- T2::fory_write_data(v, context, is_field);
+ T2::fory_write_data(v, fory, context, is_field);
}
None => todo!(),
}
}
fn read_data<T2: 'static + Serializer + ForyDefault>(
+ fory: &Fory,
context: &mut ReadContext,
is_field: bool,
) -> Result<Box<dyn Any>, Error> {
- match T2::fory_read_data(context, is_field) {
+ match T2::fory_read_data(fory, context, is_field) {
Ok(v) => Ok(Box::new(v)),
Err(e) => Err(e),
}
@@ -364,13 +374,13 @@ impl TypeResolver {
self.type_name_map.insert(rs_type_id, key.clone());
self.name_serializer_map.insert(
key,
- Harness::new(
+ Arc::from(Harness::new(
write::<T>,
read::<T>,
write_data::<T>,
read_data::<T>,
to_serializer::<T>,
- ),
+ )),
);
} else {
let type_id = type_info.type_id;
@@ -380,13 +390,13 @@ impl TypeResolver {
self.type_id_map.insert(rs_type_id, type_id);
self.serializer_map.insert(
type_id,
- Harness::new(
+ Arc::from(Harness::new(
write::<T>,
read::<T>,
write_data::<T>,
read_data::<T>,
to_serializer::<T>,
- ),
+ )),
);
}
}
@@ -394,30 +404,32 @@ impl TypeResolver {
pub fn register_serializer<T: Serializer + ForyDefault>(&mut self, type_info: &TypeInfo) {
fn write<T2: 'static + Serializer>(
this: &dyn Any,
+ fory: &Fory,
context: &mut WriteContext,
is_field: bool,
) {
let this = this.downcast_ref::<T2>();
match this {
Some(v) => {
- v.fory_write(context, is_field);
+ v.fory_write(fory, context, is_field);
}
None => todo!(),
}
}
fn read<T2: 'static + Serializer + ForyDefault>(
+ fory: &Fory,
context: &mut ReadContext,
is_field: bool,
skip_ref_flag: bool,
) -> Result<Box<dyn Any>, Error> {
if skip_ref_flag {
- match T2::fory_read_data(context, is_field) {
+ match T2::fory_read_data(fory, context, is_field) {
Ok(v) => Ok(Box::new(v)),
Err(e) => Err(e),
}
} else {
- match T2::fory_read(context, is_field) {
+ match T2::fory_read(fory, context, is_field) {
Ok(v) => Ok(Box::new(v)),
Err(e) => Err(e),
}
@@ -426,23 +438,25 @@ impl TypeResolver {
fn write_data<T2: 'static + Serializer>(
this: &dyn Any,
+ fory: &Fory,
context: &mut WriteContext,
is_field: bool,
) {
let this = this.downcast_ref::<T2>();
match this {
Some(v) => {
- T2::fory_write_data(v, context, is_field);
+ T2::fory_write_data(v, fory, context, is_field);
}
None => todo!(),
}
}
fn read_data<T2: 'static + Serializer + ForyDefault>(
+ fory: &Fory,
context: &mut ReadContext,
is_field: bool,
) -> Result<Box<dyn Any>, Error> {
- match T2::fory_read_data(context, is_field) {
+ match T2::fory_read_data(fory, context, is_field) {
Ok(v) => Ok(Box::new(v)),
Err(e) => Err(e),
}
@@ -450,9 +464,9 @@ impl TypeResolver {
fn to_serializer<T2: 'static + Serializer>(
boxed_any: Box<dyn Any>,
- ) -> Result<Box<dyn crate::serializer::Serializer>, Error> {
+ ) -> Result<Box<dyn Serializer>, Error> {
match boxed_any.downcast::<T2>() {
- Ok(concrete) => Ok(Box::new(*concrete) as Box<dyn crate::serializer::Serializer>),
+ Ok(concrete) => Ok(Box::new(*concrete) as Box<dyn Serializer>),
Err(_) => Err(Error::Other(anyhow::anyhow!(
"Failed to downcast to concrete type"
))),
@@ -477,13 +491,13 @@ impl TypeResolver {
self.type_name_map.insert(rs_type_id, key.clone());
self.name_serializer_map.insert(
key,
- Harness::new(
+ Arc::from(Harness::new(
write::<T>,
read::<T>,
write_data::<T>,
read_data::<T>,
to_serializer::<T>,
- ),
+ )),
);
} else {
let type_id = type_info.type_id;
@@ -493,32 +507,28 @@ impl TypeResolver {
self.type_id_map.insert(rs_type_id, type_id);
self.serializer_map.insert(
type_id,
- Harness::new(
+ Arc::from(Harness::new(
write::<T>,
read::<T>,
write_data::<T>,
read_data::<T>,
to_serializer::<T>,
- ),
+ )),
);
}
}
- pub fn get_harness_by_type(&self, type_id: std::any::TypeId) -> Option<&Harness> {
- self.get_harness(*self.type_id_map.get(&type_id).unwrap())
- }
-
- pub fn get_harness(&self, id: u32) -> Option<&Harness> {
- self.serializer_map.get(&id)
+ pub fn get_harness(&self, id: u32) -> Option<Arc<Harness>> {
+ self.serializer_map.get(&id).cloned()
}
pub fn get_name_harness(
&self,
namespace: &MetaString,
type_name: &MetaString,
- ) -> Option<&Harness> {
+ ) -> Option<Arc<Harness>> {
let key = (namespace.clone(), type_name.clone());
- self.name_serializer_map.get(&key)
+ self.name_serializer_map.get(&key).cloned()
}
pub fn get_ext_harness(&self, id: u32) -> &Harness {
@@ -537,14 +547,14 @@ impl TypeResolver {
pub fn get_sorted_field_names<T: StructSerializer>(
&self,
type_id: std::any::TypeId,
- ) -> Option<Vec<String>> {
- let map = self.sorted_field_names_map.borrow();
+ ) -> Option<Arc<Vec<String>>> {
+ let map = self.sorted_field_names_map.read().unwrap();
map.get(&type_id).cloned()
}
- pub fn set_sorted_field_names<T: StructSerializer>(&self, field_names: &[String]) {
- let mut map = self.sorted_field_names_map.borrow_mut();
- map.insert(std::any::TypeId::of::<T>(), field_names.to_owned());
+ pub fn set_sorted_field_names<T: StructSerializer>(&self, field_names: Arc<Vec<String>>) {
+ let mut map = self.sorted_field_names_map.write().unwrap();
+ map.insert(std::any::TypeId::of::<T>(), field_names);
}
pub fn get_fory_type_id(&self, rust_type_id: std::any::TypeId) -> Option<u32> {
diff --git a/rust/fory-core/src/serializer/any.rs b/rust/fory-core/src/serializer/any.rs
index d82b162a7..745c687b3 100644
--- a/rust/fory-core/src/serializer/any.rs
+++ b/rust/fory-core/src/serializer/any.rs
@@ -25,17 +25,22 @@ use std::rc::Rc;
use std::sync::Arc;
/// Helper function to serialize a `Box<dyn Any>`
-pub fn serialize_any_box(any_box: &Box<dyn Any>, context: &mut WriteContext, is_field: bool) {
+pub fn serialize_any_box(
+ any_box: &Box<dyn Any>,
+ fory: &Fory,
+ context: &mut WriteContext,
+ is_field: bool,
+) {
context.writer.write_i8(RefFlag::NotNullValue as i8);
let concrete_type_id = (**any_box).type_id();
- let harness = context.write_any_typeinfo(concrete_type_id);
+ let harness = context.write_any_typeinfo(fory, concrete_type_id);
let serializer_fn = harness.get_write_data_fn();
- serializer_fn(&**any_box, context, is_field);
+ serializer_fn(&**any_box, fory, context, is_field);
}
/// Helper function to deserialize to `Box<dyn Any>`
-pub fn deserialize_any_box(context: &mut ReadContext) -> Result<Box<dyn Any>, Error> {
+pub fn deserialize_any_box(fory: &Fory, context: &mut ReadContext) -> Result<Box<dyn Any>, Error> {
context.inc_depth()?;
let ref_flag = context.reader.read_i8();
if ref_flag != RefFlag::NotNullValue as i8 {
@@ -43,9 +48,9 @@ pub fn deserialize_any_box(context: &mut ReadContext) -> Result<Box<dyn Any>, Er
"Expected NotNullValue for Box<dyn Any>"
)));
}
- let harness = context.read_any_typeinfo();
+ let harness = context.read_any_typeinfo(fory);
let deserializer_fn = harness.get_read_data_fn();
- let result = deserializer_fn(context, true);
+ let result = deserializer_fn(fory, context, true);
context.dec_depth();
result
}
@@ -57,20 +62,24 @@ impl ForyDefault for Box<dyn Any> {
}
impl Serializer for Box<dyn Any> {
- fn fory_write(&self, context: &mut WriteContext, is_field: bool) {
- serialize_any_box(self, context, is_field);
+ fn fory_write(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ serialize_any_box(self, fory, context, is_field);
}
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- serialize_any_box(self, context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ serialize_any_box(self, fory, context, is_field);
}
- fn fory_read(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
- deserialize_any_box(context)
+ fn fory_read(fory: &Fory, context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ deserialize_any_box(fory, context)
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
- deserialize_any_box(context)
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
+ deserialize_any_box(fory, context)
}
fn fory_get_type_id(_fory: &Fory) -> u32 {
@@ -88,11 +97,11 @@ impl Serializer for Box<dyn Any> {
true
}
- fn fory_write_type_info(_context: &mut WriteContext, _is_field: bool) {
+ fn fory_write_type_info(_fory: &Fory, _context: &mut WriteContext, _is_field: bool) {
// Box<dyn Any> is polymorphic - type info is written per element
}
- fn fory_read_type_info(_context: &mut ReadContext, _is_field: bool) {
+ fn fory_read_type_info(_fory: &Fory, _context: &mut ReadContext, _is_field: bool) {
// Box<dyn Any> is polymorphic - type info is read per element
}
@@ -108,20 +117,23 @@ impl ForyDefault for Rc<dyn Any> {
}
impl Serializer for Rc<dyn Any> {
- fn fory_write(&self, context: &mut WriteContext, is_field: bool) {
- if !context.ref_writer.try_write_rc_ref(context.writer, self) {
+ fn fory_write(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ if !context
+ .ref_writer
+ .try_write_rc_ref(&mut context.writer, self)
+ {
let concrete_type_id = (**self).type_id();
- let harness = context.write_any_typeinfo(concrete_type_id);
+ let harness = context.write_any_typeinfo(fory, concrete_type_id);
let serializer_fn = harness.get_write_data_fn();
- serializer_fn(&**self, context, is_field);
+ serializer_fn(&**self, fory, context, is_field);
}
}
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- self.fory_write(context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ self.fory_write(fory, context, is_field);
}
- fn fory_read(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read(fory: &Fory, context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader);
match ref_flag {
@@ -137,17 +149,17 @@ impl Serializer for Rc<dyn Any> {
}
RefFlag::NotNullValue => {
context.inc_depth()?;
- let harness = context.read_any_typeinfo();
+ let harness = context.read_any_typeinfo(fory);
let deserializer_fn = harness.get_read_data_fn();
- let boxed = deserializer_fn(context, true)?;
+ let boxed = deserializer_fn(fory, context, true)?;
context.dec_depth();
Ok(Rc::<dyn Any>::from(boxed))
}
RefFlag::RefValue => {
context.inc_depth()?;
- let harness = context.read_any_typeinfo();
+ let harness = context.read_any_typeinfo(fory);
let deserializer_fn = harness.get_read_data_fn();
- let boxed = deserializer_fn(context, true)?;
+ let boxed = deserializer_fn(fory, context, true)?;
context.dec_depth();
let rc: Rc<dyn Any> = Rc::from(boxed);
context.ref_reader.store_rc_ref(rc.clone());
@@ -156,8 +168,12 @@ impl Serializer for Rc<dyn Any> {
}
}
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
- Self::fory_read(context, is_field)
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
+ Self::fory_read(fory, context, is_field)
}
fn fory_get_type_id(_fory: &Fory) -> u32 {
@@ -175,11 +191,11 @@ impl Serializer for Rc<dyn Any> {
true
}
- fn fory_write_type_info(_context: &mut WriteContext, _is_field: bool) {
+ fn fory_write_type_info(_fory: &Fory, _context: &mut WriteContext, _is_field: bool) {
// Rc<dyn Any> is polymorphic - type info is written per element
}
- fn fory_read_type_info(_context: &mut ReadContext, _is_field: bool) {
+ fn fory_read_type_info(_fory: &Fory, _context: &mut ReadContext, _is_field: bool) {
// Rc<dyn Any> is polymorphic - type info is read per element
}
@@ -195,20 +211,23 @@ impl ForyDefault for Arc<dyn Any> {
}
impl Serializer for Arc<dyn Any> {
- fn fory_write(&self, context: &mut WriteContext, is_field: bool) {
- if !context.ref_writer.try_write_arc_ref(context.writer, self) {
+ fn fory_write(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ if !context
+ .ref_writer
+ .try_write_arc_ref(&mut context.writer, self)
+ {
let concrete_type_id = (**self).type_id();
- let harness = context.write_any_typeinfo(concrete_type_id);
+ let harness = context.write_any_typeinfo(fory, concrete_type_id);
let serializer_fn = harness.get_write_data_fn();
- serializer_fn(&**self, context, is_field);
+ serializer_fn(&**self, fory, context, is_field);
}
}
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- self.fory_write(context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ self.fory_write(fory, context, is_field);
}
- fn fory_read(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read(fory: &Fory, context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader);
match ref_flag {
@@ -224,17 +243,17 @@ impl Serializer for Arc<dyn Any> {
}
RefFlag::NotNullValue => {
context.inc_depth()?;
- let harness = context.read_any_typeinfo();
+ let harness = context.read_any_typeinfo(fory);
let deserializer_fn = harness.get_read_data_fn();
- let boxed = deserializer_fn(context, true)?;
+ let boxed = deserializer_fn(fory, context, true)?;
context.dec_depth();
Ok(Arc::<dyn Any>::from(boxed))
}
RefFlag::RefValue => {
context.inc_depth()?;
- let harness = context.read_any_typeinfo();
+ let harness = context.read_any_typeinfo(fory);
let deserializer_fn = harness.get_read_data_fn();
- let boxed = deserializer_fn(context, true)?;
+ let boxed = deserializer_fn(fory, context, true)?;
context.dec_depth();
let arc: Arc<dyn Any> = Arc::from(boxed);
context.ref_reader.store_arc_ref(arc.clone());
@@ -243,8 +262,12 @@ impl Serializer for Arc<dyn Any> {
}
}
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
- Self::fory_read(context, is_field)
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
+ Self::fory_read(fory, context, is_field)
}
fn fory_get_type_id(_fory: &Fory) -> u32 {
@@ -262,11 +285,11 @@ impl Serializer for Arc<dyn Any> {
true
}
- fn fory_write_type_info(_context: &mut WriteContext, _is_field: bool) {
+ fn fory_write_type_info(_fory: &Fory, _context: &mut WriteContext, _is_field: bool) {
// Arc<dyn Any> is polymorphic - type info is written per element
}
- fn fory_read_type_info(_context: &mut ReadContext, _is_field: bool) {
+ fn fory_read_type_info(_fory: &Fory, _context: &mut ReadContext, _is_field: bool) {
// Arc<dyn Any> is polymorphic - type info is read per element
}
diff --git a/rust/fory-core/src/serializer/arc.rs b/rust/fory-core/src/serializer/arc.rs
index f62b2e119..cc0a0bc87 100644
--- a/rust/fory-core/src/serializer/arc.rs
+++ b/rust/fory-core/src/serializer/arc.rs
@@ -28,24 +28,27 @@ impl<T: Serializer + ForyDefault + Send + Sync + 'static> Serializer for Arc<T>
true
}
- fn fory_write(&self, context: &mut WriteContext, is_field: bool) {
- if !context.ref_writer.try_write_arc_ref(context.writer, self) {
- T::fory_write_data(self.as_ref(), context, is_field);
+ fn fory_write(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ if !context
+ .ref_writer
+ .try_write_arc_ref(&mut context.writer, self)
+ {
+ T::fory_write_data(self.as_ref(), fory, context, is_field);
}
}
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
// When Arc is nested inside another shared ref (like Rc<Arc<T>>),
// the outer ref calls fory_write_data on the inner Arc.
// We still need to track the Arc's own references here.
- self.fory_write(context, is_field);
+ self.fory_write(fory, context, is_field);
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- T::fory_write_type_info(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ T::fory_write_type_info(fory, context, is_field);
}
- fn fory_read(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
+ fn fory_read(fory: &Fory, context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader);
match ref_flag {
@@ -58,12 +61,12 @@ impl<T: Serializer + ForyDefault + Send + Sync + 'static> Serializer for Arc<T>
.ok_or_else(|| anyhow!("Arc reference {} not found", ref_id).into())
}
RefFlag::NotNullValue => {
- let inner = T::fory_read_data(context, is_field)?;
+ let inner = T::fory_read_data(fory, context, is_field)?;
Ok(Arc::new(inner))
}
RefFlag::RefValue => {
let ref_id = context.ref_reader.reserve_ref_id();
- let inner = T::fory_read_data(context, is_field)?;
+ let inner = T::fory_read_data(fory, context, is_field)?;
let arc = Arc::new(inner);
context.ref_reader.store_arc_ref_at(ref_id, arc.clone());
Ok(arc)
@@ -71,14 +74,18 @@ impl<T: Serializer + ForyDefault + Send + Sync + 'static> Serializer for Arc<T>
}
}
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
// When Arc is nested inside another shared ref, fory_read_data is called.
// Delegate to fory_read which handles ref tracking properly.
- Self::fory_read(context, is_field)
+ Self::fory_read(fory, context, is_field)
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- T::fory_read_type_info(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ T::fory_read_type_info(fory, context, is_field);
}
fn fory_reserved_space() -> usize {
diff --git a/rust/fory-core/src/serializer/bool.rs b/rust/fory-core/src/serializer/bool.rs
index aedc14ff0..c3a71449d 100644
--- a/rust/fory-core/src/serializer/bool.rs
+++ b/rust/fory-core/src/serializer/bool.rs
@@ -24,11 +24,15 @@ use crate::types::TypeId;
use std::mem;
impl Serializer for bool {
- fn fory_write_data(&self, context: &mut WriteContext, _is_field: bool) {
+ fn fory_write_data(&self, _fory: &Fory, context: &mut WriteContext, _is_field: bool) {
context.writer.write_u8(if *self { 1 } else { 0 });
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ _fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
Ok(context.reader.read_u8() == 1)
}
@@ -48,12 +52,12 @@ impl Serializer for bool {
self
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- write_type_info::<Self>(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_type_info::<Self>(fory, context, is_field);
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- read_type_info::<Self>(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ read_type_info::<Self>(fory, context, is_field);
}
}
diff --git a/rust/fory-core/src/serializer/box_.rs b/rust/fory-core/src/serializer/box_.rs
index 3715f802c..88c4c1893 100644
--- a/rust/fory-core/src/serializer/box_.rs
+++ b/rust/fory-core/src/serializer/box_.rs
@@ -22,20 +22,24 @@ use crate::resolver::context::WriteContext;
use crate::serializer::{ForyDefault, Serializer};
impl<T: Serializer + ForyDefault> Serializer for Box<T> {
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
- Ok(Box::new(T::fory_read_data(context, is_field)?))
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
+ Ok(Box::new(T::fory_read_data(fory, context, is_field)?))
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- T::fory_read_type_info(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ T::fory_read_type_info(fory, context, is_field);
}
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- T::fory_write_data(self.as_ref(), context, is_field)
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ T::fory_write_data(self.as_ref(), fory, context, is_field)
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- T::fory_write_type_info(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ T::fory_write_type_info(fory, context, is_field);
}
fn fory_reserved_space() -> usize {
diff --git a/rust/fory-core/src/serializer/collection.rs b/rust/fory-core/src/serializer/collection.rs
index b9fdda304..488bc84ee 100644
--- a/rust/fory-core/src/serializer/collection.rs
+++ b/rust/fory-core/src/serializer/collection.rs
@@ -20,6 +20,7 @@ use crate::resolver::context::ReadContext;
use crate::resolver::context::WriteContext;
use crate::serializer::{ForyDefault, Serializer};
use crate::types::PRIMITIVE_ARRAY_TYPES;
+use crate::Fory;
// const TRACKING_REF: u8 = 0b1;
@@ -42,28 +43,30 @@ pub fn write_collection_type_info(
context.writer.write_varuint32(collection_type_id);
}
-pub fn write_collection<'a, T: Serializer + 'a, I: IntoIterator<Item = &'a T>>(
- iter: I,
- context: &mut WriteContext,
- is_field: bool,
-) {
- let items: Vec<&T> = iter.into_iter().collect();
- let len = items.len();
+pub fn write_collection<'a, T, I>(iter: I, fory: &Fory, context: &mut WriteContext, is_field: bool)
+where
+ T: Serializer + 'a,
+ I: IntoIterator<Item = &'a T>,
+ I::IntoIter: ExactSizeIterator + Clone,
+{
+ let iter = iter.into_iter();
+ let len = iter.len();
context.writer.write_varuint32(len as u32);
if len == 0 {
return;
}
let mut header = 0;
let mut has_null = false;
+ let is_same_type = !T::fory_is_polymorphic();
if T::fory_is_option() {
- for item in &items {
+ // iter.clone() is zero-copy
+ for item in iter.clone() {
if item.fory_is_none() {
has_null = true;
break;
}
}
}
- let is_same_type = !T::fory_is_polymorphic();
if has_null {
header |= HAS_NULL;
}
@@ -74,18 +77,25 @@ pub fn write_collection<'a, T: Serializer + 'a, I: IntoIterator<Item = &'a T>>(
header |= IS_SAME_TYPE;
}
context.writer.write_u8(header);
- T::fory_write_type_info(context, is_field);
+ T::fory_write_type_info(fory, context, is_field);
// context.writer.reserve((T::reserved_space() + SIZE_OF_REF_AND_TYPE) * len);
if T::fory_is_polymorphic() || T::fory_is_shared_ref() {
// TOTO: make it xlang compatible
- for item in &items {
- item.fory_write(context, is_field);
+ for item in iter {
+ item.fory_write(fory, context, is_field);
}
} else {
// let skip_ref_flag = crate::serializer::get_skip_ref_flag::<T>(context.get_fory());
let skip_ref_flag = is_same_type && !has_null;
- for item in &items {
- crate::serializer::write_ref_info_data(*item, context, is_field, skip_ref_flag, true);
+ for item in iter {
+ crate::serializer::write_ref_info_data(
+ item,
+ fory,
+ context,
+ is_field,
+ skip_ref_flag,
+ true,
+ );
}
}
}
@@ -106,7 +116,7 @@ pub fn read_collection_type_info(
assert_eq!(remote_collection_type_id, collection_type_id);
}
-pub fn read_collection<C, T>(context: &mut ReadContext) -> Result<C, Error>
+pub fn read_collection<C, T>(fory: &Fory, context: &mut ReadContext) -> Result<C, Error>
where
T: Serializer + ForyDefault,
C: FromIterator<T>,
@@ -117,18 +127,20 @@ where
}
let header = context.reader.read_u8();
let declared = (header & DECL_ELEMENT_TYPE) != 0;
- T::fory_read_type_info(context, declared);
+ T::fory_read_type_info(fory, context, declared);
let has_null = (header & HAS_NULL) != 0;
let is_same_type = (header & IS_SAME_TYPE) != 0;
if T::fory_is_polymorphic() || T::fory_is_shared_ref() {
(0..len)
- .map(|_| T::fory_read(context, declared))
+ .map(|_| T::fory_read(fory, context, declared))
.collect::<Result<C, Error>>()
} else {
let skip_ref_flag = is_same_type && !has_null;
// let skip_ref_flag = crate::serializer::get_skip_ref_flag::<T>(context.get_fory());
(0..len)
- .map(|_| crate::serializer::read_ref_info_data(context, declared, skip_ref_flag, true))
+ .map(|_| {
+ crate::serializer::read_ref_info_data(fory, context, declared, skip_ref_flag, true)
+ })
.collect::<Result<C, Error>>()
}
}
diff --git a/rust/fory-core/src/serializer/datetime.rs b/rust/fory-core/src/serializer/datetime.rs
index 52bc2c714..d709227e3 100644
--- a/rust/fory-core/src/serializer/datetime.rs
+++ b/rust/fory-core/src/serializer/datetime.rs
@@ -28,13 +28,17 @@ use chrono::{DateTime, Days, NaiveDate, NaiveDateTime};
use std::mem;
impl Serializer for NaiveDateTime {
- fn fory_write_data(&self, context: &mut WriteContext, _is_field: bool) {
+ fn fory_write_data(&self, _fory: &Fory, context: &mut WriteContext, _is_field: bool) {
let dt = self.and_utc();
let micros = dt.timestamp() * 1_000_000 + dt.timestamp_subsec_micros() as i64;
context.writer.write_i64(micros);
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ _fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
let micros = context.reader.read_i64();
let seconds = micros / 1_000_000;
let subsec_micros = (micros % 1_000_000) as u32;
@@ -62,22 +66,26 @@ impl Serializer for NaiveDateTime {
self
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- write_type_info::<Self>(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_type_info::<Self>(fory, context, is_field);
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- read_type_info::<Self>(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ read_type_info::<Self>(fory, context, is_field);
}
}
impl Serializer for NaiveDate {
- fn fory_write_data(&self, context: &mut WriteContext, _is_field: bool) {
+ fn fory_write_data(&self, _fory: &Fory, context: &mut WriteContext, _is_field: bool) {
let days_since_epoch = self.signed_duration_since(EPOCH).num_days();
context.writer.write_i32(days_since_epoch as i32);
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ _fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
let days = context.reader.read_i32();
EPOCH
.checked_add_days(Days::new(days as u64))
@@ -102,12 +110,12 @@ impl Serializer for NaiveDate {
self
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- write_type_info::<Self>(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_type_info::<Self>(fory, context, is_field);
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- read_type_info::<Self>(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ read_type_info::<Self>(fory, context, is_field);
}
}
diff --git a/rust/fory-core/src/serializer/enum_.rs b/rust/fory-core/src/serializer/enum_.rs
index c1ae7c7e3..fa3c4c245 100644
--- a/rust/fory-core/src/serializer/enum_.rs
+++ b/rust/fory-core/src/serializer/enum_.rs
@@ -44,73 +44,68 @@ pub fn type_def(
}
#[inline(always)]
-pub fn write_type_info<T: Serializer>(context: &mut WriteContext, is_field: bool) {
+pub fn write_type_info<T: Serializer>(fory: &Fory, context: &mut WriteContext, is_field: bool) {
if is_field {
return;
}
- let type_id = T::fory_get_type_id(context.get_fory());
+ let type_id = T::fory_get_type_id(fory);
context.writer.write_varuint32(type_id);
let is_named_enum = type_id & 0xff == TypeId::NAMED_ENUM as u32;
if !is_named_enum {
return;
}
let rs_type_id = std::any::TypeId::of::<T>();
- if context.get_fory().is_share_meta() {
- let meta_index = context.push_meta(rs_type_id) as u32;
+ if fory.is_share_meta() {
+ let meta_index = context.push_meta(fory, rs_type_id) as u32;
context.writer.write_varuint32(meta_index);
} else {
- let type_info = context
- .get_fory()
- .get_type_resolver()
- .get_type_info(rs_type_id);
+ let type_info = fory.get_type_resolver().get_type_info(rs_type_id);
let namespace = type_info.get_namespace().to_owned();
let type_name = type_info.get_type_name().to_owned();
- let resolver = context.get_fory().get_metastring_resolver();
- resolver
- .borrow_mut()
- .write_meta_string_bytes(context, &namespace);
- resolver
- .borrow_mut()
- .write_meta_string_bytes(context, &type_name);
+ context.write_meta_string_bytes(&namespace);
+ context.write_meta_string_bytes(&type_name);
}
}
#[inline(always)]
-pub fn read_type_info<T: Serializer>(context: &mut ReadContext, is_field: bool) {
+pub fn read_type_info<T: Serializer>(fory: &Fory, context: &mut ReadContext, is_field: bool) {
if is_field {
return;
}
- let local_type_id = T::fory_get_type_id(context.get_fory());
+ let local_type_id = T::fory_get_type_id(fory);
let remote_type_id = context.reader.read_varuint32();
assert_eq!(local_type_id, remote_type_id);
let is_named_enum = local_type_id & 0xff == TypeId::NAMED_ENUM as u32;
if !is_named_enum {
return;
}
- if context.get_fory().is_share_meta() {
+ if fory.is_share_meta() {
let _meta_index = context.reader.read_varuint32();
} else {
- let resolver = context.get_fory().get_metastring_resolver();
- resolver.borrow_mut().read_meta_string_bytes(context);
- resolver.borrow_mut().read_meta_string_bytes(context);
+ let _namespace_msb = context.read_meta_string_bytes();
+ let _type_name_msb = context.read_meta_string_bytes();
}
}
#[inline(always)]
-pub fn read_compatible<T: Serializer + ForyDefault>(context: &mut ReadContext) -> Result<T, Error> {
- T::fory_read_type_info(context, true);
- T::fory_read_data(context, true)
+pub fn read_compatible<T: Serializer + ForyDefault>(
+ fory: &Fory,
+ context: &mut ReadContext,
+) -> Result<T, Error> {
+ T::fory_read_type_info(fory, context, true);
+ T::fory_read_data(fory, context, true)
}
#[inline(always)]
-pub fn write<T: Serializer>(this: &T, context: &mut WriteContext, is_field: bool) {
+pub fn write<T: Serializer>(this: &T, fory: &Fory, context: &mut WriteContext, is_field: bool) {
context.writer.write_i8(RefFlag::NotNullValue as i8);
- T::fory_write_type_info(context, is_field);
- this.fory_write_data(context, is_field);
+ T::fory_write_type_info(fory, context, is_field);
+ this.fory_write_data(fory, context, is_field);
}
#[inline(always)]
pub fn read<T: Serializer + ForyDefault>(
+ fory: &Fory,
context: &mut ReadContext,
is_field: bool,
) -> Result<T, Error> {
@@ -118,8 +113,8 @@ pub fn read<T: Serializer + ForyDefault>(
if ref_flag == RefFlag::Null as i8 {
Ok(T::fory_default())
} else if ref_flag == (RefFlag::NotNullValue as i8) {
- T::fory_read_type_info(context, false);
- T::fory_read_data(context, is_field)
+ T::fory_read_type_info(fory, context, false);
+ T::fory_read_data(fory, context, is_field)
} else {
unimplemented!()
}
diff --git a/rust/fory-core/src/serializer/heap.rs b/rust/fory-core/src/serializer/heap.rs
index 6e9d56d45..f61b6095c 100644
--- a/rust/fory-core/src/serializer/heap.rs
+++ b/rust/fory-core/src/serializer/heap.rs
@@ -29,19 +29,23 @@ use std::collections::BinaryHeap;
use std::mem;
impl<T: Serializer + ForyDefault + Ord> Serializer for BinaryHeap<T> {
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- write_collection(self, context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_collection(self, fory, context, is_field);
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
+ fn fory_write_type_info(_fory: &Fory, context: &mut WriteContext, is_field: bool) {
write_collection_type_info(context, is_field, TypeId::SET as u32);
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
- read_collection(context)
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
+ read_collection(fory, context)
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
+ fn fory_read_type_info(_fory: &Fory, context: &mut ReadContext, is_field: bool) {
read_collection_type_info(context, is_field, TypeId::SET as u32)
}
diff --git a/rust/fory-core/src/serializer/list.rs b/rust/fory-core/src/serializer/list.rs
index f60d9641f..61b6d9904 100644
--- a/rust/fory-core/src/serializer/list.rs
+++ b/rust/fory-core/src/serializer/list.rs
@@ -44,18 +44,18 @@ fn check_primitive<T: 'static>() -> Option<TypeId> {
}
impl<T: Serializer + ForyDefault> Serializer for Vec<T> {
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
match check_primitive::<T>() {
Some(_) => {
primitive_list::fory_write_data(self, context);
}
None => {
- write_collection(self, context, is_field);
+ write_collection(self, fory, context, is_field);
}
}
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
+ fn fory_write_type_info(_fory: &Fory, context: &mut WriteContext, is_field: bool) {
match check_primitive::<T>() {
Some(type_id) => {
primitive_list::fory_write_type_info(context, is_field, type_id);
@@ -66,14 +66,18 @@ impl<T: Serializer + ForyDefault> Serializer for Vec<T> {
}
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
match check_primitive::<T>() {
Some(_) => primitive_list::fory_read_data(context),
- None => read_collection(context),
+ None => read_collection(fory, context),
}
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
+ fn fory_read_type_info(_fory: &Fory, context: &mut ReadContext, is_field: bool) {
match check_primitive::<T>() {
Some(type_id) => primitive_list::fory_read_type_info(context, is_field, type_id),
None => read_collection_type_info(context, is_field, TypeId::LIST as u32),
@@ -116,19 +120,23 @@ impl<T> ForyDefault for Vec<T> {
}
impl<T: Serializer + ForyDefault> Serializer for VecDeque<T> {
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- write_collection(self, context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_collection(self, fory, context, is_field);
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
+ fn fory_write_type_info(_fory: &Fory, context: &mut WriteContext, is_field: bool) {
write_collection_type_info(context, is_field, TypeId::LIST as u32);
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
- read_collection(context)
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
+ read_collection(fory, context)
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
+ fn fory_read_type_info(_fory: &Fory, context: &mut ReadContext, is_field: bool) {
read_collection_type_info(context, is_field, TypeId::LIST as u32);
}
@@ -156,19 +164,23 @@ impl<T> ForyDefault for VecDeque<T> {
}
impl<T: Serializer + ForyDefault> Serializer for LinkedList<T> {
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- write_collection(self, context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_collection(self, fory, context, is_field);
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
+ fn fory_write_type_info(_fory: &Fory, context: &mut WriteContext, is_field: bool) {
write_collection_type_info(context, is_field, TypeId::LIST as u32);
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
- read_collection(context)
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
+ read_collection(fory, context)
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
+ fn fory_read_type_info(_fory: &Fory, context: &mut ReadContext, is_field: bool) {
read_collection_type_info(context, is_field, TypeId::LIST as u32);
}
diff --git a/rust/fory-core/src/serializer/map.rs b/rust/fory-core/src/serializer/map.rs
index 7db4fc8f9..f7b650a82 100644
--- a/rust/fory-core/src/serializer/map.rs
+++ b/rust/fory-core/src/serializer/map.rs
@@ -35,7 +35,8 @@ const TRACKING_VALUE_REF: u8 = 0b1000;
pub const VALUE_NULL: u8 = 0b10000;
const DECL_VALUE_TYPE: u8 = 0b100000;
-fn check_and_write_null<K: Serializer, V: Serializer>(
+fn check_and_write_null<K: Serializer + Eq + std::hash::Hash, V: Serializer>(
+ fory: &Fory,
context: &mut WriteContext,
is_field: bool,
key: &K,
@@ -49,7 +50,7 @@ fn check_and_write_null<K: Serializer, V: Serializer>(
let mut chunk_header = KEY_NULL;
let skip_ref_flag;
if is_field {
- skip_ref_flag = crate::serializer::get_skip_ref_flag::<V>(context.get_fory());
+ skip_ref_flag = crate::serializer::get_skip_ref_flag::<V>(fory);
chunk_header |= DECL_VALUE_TYPE;
} else {
skip_ref_flag = false;
@@ -57,7 +58,7 @@ fn check_and_write_null<K: Serializer, V: Serializer>(
}
context.writer.write_u8(chunk_header);
- write_ref_info_data(value, context, is_field, skip_ref_flag, false);
+ write_ref_info_data(value, fory, context, is_field, skip_ref_flag, false);
return true;
}
if value.fory_is_none() {
@@ -72,7 +73,7 @@ fn check_and_write_null<K: Serializer, V: Serializer>(
chunk_header |= TRACKING_KEY_REF;
}
context.writer.write_u8(chunk_header);
- write_ref_info_data(key, context, is_field, skip_ref_flag, false);
+ write_ref_info_data(key, fory, context, is_field, skip_ref_flag, false);
return true;
}
false
@@ -82,9 +83,14 @@ fn write_chunk_size(context: &mut WriteContext, header_offset: usize, size: u8)
context.writer.set_bytes(header_offset + 1, &[size]);
}
-fn write_map_data<'a, K, V, I>(iter: I, length: usize, context: &mut WriteContext, is_field: bool)
-where
- K: Serializer + ForyDefault + 'a,
+fn write_map_data<'a, K, V, I>(
+ iter: I,
+ length: usize,
+ fory: &Fory,
+ context: &mut WriteContext,
+ is_field: bool,
+) where
+ K: Serializer + ForyDefault + 'a + Eq + std::hash::Hash,
V: Serializer + ForyDefault + 'a,
I: Iterator<Item = (&'a K, &'a V)>,
{
@@ -103,7 +109,7 @@ where
let mut skip_val_ref_flag = false;
for (key, value) in iter {
if need_write_header {
- if check_and_write_null(context, is_field, key, value) {
+ if check_and_write_null(fory, context, is_field, key, value) {
continue;
}
header_offset = context.writer.len();
@@ -120,8 +126,8 @@ where
if !skip_val_ref_flag {
chunk_header |= TRACKING_VALUE_REF;
}
- K::fory_write_type_info(context, is_field);
- V::fory_write_type_info(context, is_field);
+ K::fory_write_type_info(fory, context, is_field);
+ V::fory_write_type_info(fory, context, is_field);
context.writer.set_bytes(header_offset, &[chunk_header]);
need_write_header = false;
}
@@ -129,18 +135,18 @@ where
write_chunk_size(context, header_offset, pair_counter);
pair_counter = 0;
need_write_header = true;
- check_and_write_null(context, is_field, key, value);
+ check_and_write_null(fory, context, is_field, key, value);
continue;
}
if K::fory_is_polymorphic() || K::fory_is_shared_ref() {
- key.fory_write(context, is_field);
+ key.fory_write(fory, context, is_field);
} else {
- write_ref_info_data(key, context, is_field, skip_key_ref_flag, true);
+ write_ref_info_data(key, fory, context, is_field, skip_key_ref_flag, true);
}
if V::fory_is_polymorphic() || V::fory_is_shared_ref() {
- value.fory_write(context, is_field);
+ value.fory_write(fory, context, is_field);
} else {
- write_ref_info_data(value, context, is_field, skip_val_ref_flag, true);
+ write_ref_info_data(value, fory, context, is_field, skip_val_ref_flag, true);
}
pair_counter += 1;
if pair_counter == MAX_CHUNK_SIZE {
@@ -157,11 +163,15 @@ where
impl<K: Serializer + ForyDefault + Eq + std::hash::Hash, V: Serializer + ForyDefault> Serializer
for HashMap<K, V>
{
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- write_map_data(self.iter(), self.len(), context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_map_data(self.iter(), self.len(), fory, context, is_field);
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
let len = context.reader.read_varuint32();
let mut map = HashMap::<K, V>::with_capacity(len as usize);
if len == 0 {
@@ -182,40 +192,43 @@ impl<K: Serializer + ForyDefault + Eq + std::hash::Hash, V: Serializer + ForyDef
let value_declared = (header & DECL_VALUE_TYPE) != 0;
if header & KEY_NULL != 0 {
let skip_ref_flag = if value_declared {
- crate::serializer::get_skip_ref_flag::<V>(context.get_fory())
+ crate::serializer::get_skip_ref_flag::<V>(fory)
} else {
false
};
- let value = read_ref_info_data(context, value_declared, skip_ref_flag, false)?;
+ let value =
+ read_ref_info_data(fory, context, value_declared, skip_ref_flag, false)?;
map.insert(K::fory_default(), value);
len_counter += 1;
continue;
}
if header & VALUE_NULL != 0 {
let skip_ref_flag = if key_declared {
- crate::serializer::get_skip_ref_flag::<K>(context.get_fory())
+ crate::serializer::get_skip_ref_flag::<K>(fory)
} else {
false
};
- let key = read_ref_info_data(context, key_declared, skip_ref_flag, false)?;
+ let key = read_ref_info_data(fory, context, key_declared, skip_ref_flag, false)?;
map.insert(key, V::fory_default());
len_counter += 1;
continue;
}
let chunk_size = context.reader.read_u8();
- K::fory_read_type_info(context, key_declared);
- V::fory_read_type_info(context, value_declared);
+ K::fory_read_type_info(fory, context, key_declared);
+ V::fory_read_type_info(fory, context, value_declared);
assert!(len_counter + chunk_size as u32 <= len);
for _ in 0..chunk_size {
let key = if K::fory_is_polymorphic() {
- K::fory_read(context, key_declared)?
+ K::fory_read(fory, context, key_declared)?
} else {
- read_ref_info_data(context, key_declared, true, true)?
+ // let skip_ref_flag = crate::serializer::get_skip_ref_flag::<K>(context.get_fory());
+ read_ref_info_data(fory, context, key_declared, true, true)?
};
let value = if V::fory_is_polymorphic() {
- V::fory_read(context, value_declared)?
+ V::fory_read(fory, context, value_declared)?
} else {
- read_ref_info_data(context, value_declared, true, true)?
+ // let skip_ref_flag = crate::serializer::get_skip_ref_flag::<V>(context.get_fory());
+ read_ref_info_data(fory, context, value_declared, true, true)?
};
map.insert(key, value);
}
@@ -240,12 +253,12 @@ impl<K: Serializer + ForyDefault + Eq + std::hash::Hash, V: Serializer + ForyDef
self
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- write_type_info::<Self>(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_type_info::<Self>(fory, context, is_field);
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- read_type_info::<Self>(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ read_type_info::<Self>(fory, context, is_field);
}
}
@@ -255,12 +268,18 @@ impl<K, V> ForyDefault for HashMap<K, V> {
}
}
-impl<K: Serializer + ForyDefault + Ord, V: Serializer + ForyDefault> Serializer for BTreeMap<K, V> {
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- write_map_data(self.iter(), self.len(), context, is_field);
+impl<K: Serializer + ForyDefault + Ord + std::hash::Hash, V: Serializer + ForyDefault> Serializer
+ for BTreeMap<K, V>
+{
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_map_data(self.iter(), self.len(), fory, context, is_field);
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
let len = context.reader.read_varuint32();
let mut map = BTreeMap::<K, V>::new();
if len == 0 {
@@ -281,40 +300,41 @@ impl<K: Serializer + ForyDefault + Ord, V: Serializer + ForyDefault> Serializer
let value_declared = (header & DECL_VALUE_TYPE) != 0;
if header & KEY_NULL != 0 {
let skip_ref_flag = if value_declared {
- crate::serializer::get_skip_ref_flag::<V>(context.get_fory())
+ crate::serializer::get_skip_ref_flag::<V>(fory)
} else {
false
};
- let value = read_ref_info_data(context, value_declared, skip_ref_flag, false)?;
+ let value =
+ read_ref_info_data(fory, context, value_declared, skip_ref_flag, false)?;
map.insert(K::fory_default(), value);
len_counter += 1;
continue;
}
if header & VALUE_NULL != 0 {
let skip_ref_flag = if key_declared {
- crate::serializer::get_skip_ref_flag::<K>(context.get_fory())
+ crate::serializer::get_skip_ref_flag::<K>(fory)
} else {
false
};
- let key = read_ref_info_data(context, key_declared, skip_ref_flag, false)?;
+ let key = read_ref_info_data(fory, context, key_declared, skip_ref_flag, false)?;
map.insert(key, V::fory_default());
len_counter += 1;
continue;
}
let chunk_size = context.reader.read_u8();
- K::fory_read_type_info(context, key_declared);
- V::fory_read_type_info(context, value_declared);
+ K::fory_read_type_info(fory, context, key_declared);
+ V::fory_read_type_info(fory, context, value_declared);
assert!(len_counter + chunk_size as u32 <= len);
for _ in 0..chunk_size {
let key = if K::fory_is_polymorphic() {
- K::fory_read(context, key_declared)?
+ K::fory_read(fory, context, key_declared)?
} else {
- read_ref_info_data(context, key_declared, true, true)?
+ read_ref_info_data(fory, context, key_declared, true, true)?
};
let value = if V::fory_is_polymorphic() {
- V::fory_read(context, value_declared)?
+ V::fory_read(fory, context, value_declared)?
} else {
- read_ref_info_data(context, value_declared, true, true)?
+ read_ref_info_data(fory, context, value_declared, true, true)?
};
map.insert(key, value);
}
@@ -339,12 +359,12 @@ impl<K: Serializer + ForyDefault + Ord, V: Serializer + ForyDefault> Serializer
self
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- write_type_info::<Self>(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_type_info::<Self>(fory, context, is_field);
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- read_type_info::<Self>(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ read_type_info::<Self>(fory, context, is_field);
}
}
diff --git a/rust/fory-core/src/serializer/mod.rs b/rust/fory-core/src/serializer/mod.rs
index 10d300c69..0f3221f7f 100644
--- a/rust/fory-core/src/serializer/mod.rs
+++ b/rust/fory-core/src/serializer/mod.rs
@@ -22,6 +22,7 @@ use crate::resolver::context::{ReadContext, WriteContext};
use crate::types::{Mode, RefFlag, TypeId, PRIMITIVE_TYPES};
use anyhow::anyhow;
use std::any::Any;
+use std::sync::Arc;
pub mod any;
mod arc;
@@ -48,6 +49,7 @@ pub mod weak;
pub fn write_ref_info_data<T: Serializer + 'static>(
record: &T,
+ fory: &Fory,
context: &mut WriteContext,
is_field: bool,
skip_ref_flag: bool,
@@ -60,13 +62,14 @@ pub fn write_ref_info_data<T: Serializer + 'static>(
context.writer.write_i8(RefFlag::NotNullValue as i8);
}
if !skip_type_info {
- T::fory_write_type_info(context, is_field);
+ T::fory_write_type_info(fory, context, is_field);
}
- record.fory_write_data(context, is_field);
+ record.fory_write_data(fory, context, is_field);
}
}
pub fn read_ref_info_data<T: Serializer + ForyDefault>(
+ fory: &Fory,
context: &mut ReadContext,
is_field: bool,
skip_ref_flag: bool,
@@ -78,15 +81,15 @@ pub fn read_ref_info_data<T: Serializer + ForyDefault>(
Ok(T::fory_default())
} else if ref_flag == (RefFlag::NotNullValue as i8) {
if !skip_type_info {
- T::fory_read_type_info(context, is_field);
+ T::fory_read_type_info(fory, context, is_field);
}
- T::fory_read_data(context, is_field)
+ T::fory_read_data(fory, context, is_field)
} else if ref_flag == (RefFlag::RefValue as i8) {
// First time seeing this referenceable object
if !skip_type_info {
- T::fory_read_type_info(context, is_field);
+ T::fory_read_type_info(fory, context, is_field);
}
- T::fory_read_data(context, is_field)
+ T::fory_read_data(fory, context, is_field)
} else if ref_flag == (RefFlag::Ref as i8) {
// This is a reference to a previously deserialized object
// For now, just return default - this should be handled by specific types
@@ -96,25 +99,25 @@ pub fn read_ref_info_data<T: Serializer + ForyDefault>(
}
} else {
if !skip_type_info {
- T::fory_read_type_info(context, is_field);
+ T::fory_read_type_info(fory, context, is_field);
}
- T::fory_read_data(context, is_field)
+ T::fory_read_data(fory, context, is_field)
}
}
-fn write_type_info<T: Serializer>(context: &mut WriteContext, is_field: bool) {
+fn write_type_info<T: Serializer>(fory: &Fory, context: &mut WriteContext, is_field: bool) {
if is_field {
return;
}
- let type_id = T::fory_get_type_id(context.get_fory());
+ let type_id = T::fory_get_type_id(fory);
context.writer.write_varuint32(type_id);
}
-fn read_type_info<T: Serializer>(context: &mut ReadContext, is_field: bool) {
+fn read_type_info<T: Serializer>(fory: &Fory, context: &mut ReadContext, is_field: bool) {
if is_field {
return;
}
- let local_type_id = T::fory_get_type_id(context.get_fory());
+ let local_type_id = T::fory_get_type_id(fory);
let remote_type_id = context.reader.read_varuint32();
assert_eq!(local_type_id, remote_type_id);
}
@@ -139,18 +142,18 @@ pub trait ForyDefault: Sized {
pub trait Serializer: 'static {
/// Entry point of the serialization.
- fn fory_write(&self, context: &mut WriteContext, is_field: bool)
+ fn fory_write(&self, fory: &Fory, context: &mut WriteContext, is_field: bool)
where
Self: Sized,
{
- write_ref_info_data(self, context, is_field, false, false);
+ write_ref_info_data(self, fory, context, is_field, false, false);
}
- fn fory_read(context: &mut ReadContext, is_field: bool) -> Result<Self, Error>
+ fn fory_read(fory: &Fory, context: &mut ReadContext, is_field: bool) -> Result<Self, Error>
where
Self: Sized + ForyDefault,
{
- read_ref_info_data(context, is_field, false, false)
+ read_ref_info_data(fory, context, is_field, false, false)
}
fn fory_is_option() -> bool
@@ -198,93 +201,86 @@ pub trait Serializer: 'static {
0
}
- fn fory_write_type_info(context: &mut WriteContext, _is_field: bool)
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, _is_field: bool)
where
Self: Sized,
{
// default implementation only for ext/named_ext
- let type_id = Self::fory_get_type_id(context.get_fory());
+ let type_id = Self::fory_get_type_id(fory);
context.writer.write_varuint32(type_id);
if type_id & 0xff == TypeId::EXT as u32 {
return;
}
let rs_type_id = std::any::TypeId::of::<Self>();
- if context.get_fory().is_share_meta() {
- let meta_index = context.push_meta(rs_type_id) as u32;
+ if fory.is_share_meta() {
+ let meta_index = context.push_meta(fory, rs_type_id) as u32;
context.writer.write_varuint32(meta_index);
} else {
let type_info = {
- let type_resolver = context.get_fory().get_type_resolver();
+ let type_resolver = fory.get_type_resolver();
type_resolver.get_type_info(rs_type_id)
};
let namespace = type_info.get_namespace().to_owned();
let type_name = type_info.get_type_name().to_owned();
- let resolver = context.get_fory().get_metastring_resolver();
- resolver
- .borrow_mut()
- .write_meta_string_bytes(context, &namespace);
- resolver
- .borrow_mut()
- .write_meta_string_bytes(context, &type_name);
+ context.write_meta_string_bytes(&namespace);
+ context.write_meta_string_bytes(&type_name);
}
}
- fn fory_read_type_info(context: &mut ReadContext, _is_field: bool)
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, _is_field: bool)
where
Self: Sized,
{
// default implementation only for ext/named_ext
- let local_type_id = Self::fory_get_type_id(context.get_fory());
+ let local_type_id = Self::fory_get_type_id(fory);
let remote_type_id = context.reader.read_varuint32();
assert_eq!(local_type_id, remote_type_id);
if local_type_id & 0xff == TypeId::EXT as u32 {
return;
}
- if context.get_fory().is_share_meta() {
+ if fory.is_share_meta() {
let _meta_index = context.reader.read_varuint32();
} else {
- let resolver = context.get_fory().get_metastring_resolver();
- resolver.borrow_mut().read_meta_string_bytes(context);
- resolver.borrow_mut().read_meta_string_bytes(context);
+ let _namespace_msb = context.read_meta_string_bytes();
+ let _type_name_msb = context.read_meta_string_bytes();
}
}
// only used by struct/enum/ext
- fn fory_read_compatible(context: &mut ReadContext) -> Result<Self, Error>
+ fn fory_read_compatible(fory: &Fory, context: &mut ReadContext) -> Result<Self, Error>
where
Self: Sized,
{
// default logic only for ext/named_ext
let remote_type_id = context.reader.read_varuint32();
- let local_type_id = Self::fory_get_type_id(context.get_fory());
+ let local_type_id = Self::fory_get_type_id(fory);
assert_eq!(remote_type_id, local_type_id);
if local_type_id & 0xff == TypeId::EXT as u32 {
- let type_resolver = context.get_fory().get_type_resolver();
+ let type_resolver = fory.get_type_resolver();
type_resolver
.get_ext_harness(local_type_id)
- .get_read_data_fn()(context, true)
+ .get_read_data_fn()(fory, context, true)
.and_then(|b: Box<dyn Any>| {
b.downcast::<Self>()
.map(|boxed_self| *boxed_self)
.map_err(|_| anyhow!("downcast to Self failed").into())
})
} else {
- let (namespace, type_name) = if context.get_fory().is_share_meta() {
+ let (namespace, type_name) = if fory.is_share_meta() {
let meta_index = context.reader.read_varuint32();
let type_def = context.get_meta(meta_index as usize);
(type_def.get_namespace(), type_def.get_type_name())
} else {
- let resolver = context.get_fory().get_metastring_resolver();
- let nsb = resolver.borrow_mut().read_meta_string_bytes(context);
- let tsb = resolver.borrow_mut().read_meta_string_bytes(context);
+ let nsb = context.read_meta_string_bytes();
+ let tsb = context.read_meta_string_bytes();
let ns = NAMESPACE_DECODER.decode(&nsb.bytes, nsb.encoding)?;
let ts = TYPE_NAME_DECODER.decode(&tsb.bytes, tsb.encoding)?;
(ns, ts)
};
- let type_resolver = context.get_fory().get_type_resolver();
+ let type_resolver = fory.get_type_resolver();
type_resolver
.get_ext_name_harness(&namespace, &type_name)
- .get_read_data_fn()(context, true)
+ .get_read_data_fn()(fory, context, true)
.and_then(|b: Box<dyn Any>| {
b.downcast::<Self>()
.map(|boxed_self| *boxed_self)
@@ -294,9 +290,13 @@ pub trait Serializer: 'static {
}
/// Write/Read the data into the buffer. Need to be implemented.
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool);
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error>
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error>
where
Self: Sized + ForyDefault;
@@ -325,7 +325,7 @@ pub trait StructSerializer: Serializer + 'static {
struct_::actual_type_id(type_id, register_by_name, mode)
}
- fn fory_get_sorted_field_names(_fory: &Fory) -> Vec<String> {
+ fn fory_get_sorted_field_names(_fory: &Fory) -> Arc<Vec<String>> {
unimplemented!()
}
}
diff --git a/rust/fory-core/src/serializer/mutex.rs b/rust/fory-core/src/serializer/mutex.rs
index b7d8c540e..a16e22f71 100644
--- a/rust/fory-core/src/serializer/mutex.rs
+++ b/rust/fory-core/src/serializer/mutex.rs
@@ -52,21 +52,21 @@ use std::sync::Mutex;
/// Simply delegates to the serializer for `T`, allowing thread-safe interior mutable
/// containers to be included in serialized graphs.
impl<T: Serializer + ForyDefault> Serializer for Mutex<T> {
- fn fory_write(&self, context: &mut WriteContext, is_field: bool) {
+ fn fory_write(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
// Don't add ref tracking for Mutex itself, just delegate to inner type
// The inner type will handle its own ref tracking
let guard = self.lock().unwrap();
- T::fory_write(&*guard, context, is_field);
+ T::fory_write(&*guard, fory, context, is_field);
}
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
// When called from Rc/Arc, just delegate to inner type's data serialization
let guard = self.lock().unwrap();
- T::fory_write_data(&*guard, context, is_field);
+ T::fory_write_data(&*guard, fory, context, is_field);
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- T::fory_write_type_info(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ T::fory_write_type_info(fory, context, is_field);
}
fn fory_reserved_space() -> usize {
@@ -74,19 +74,23 @@ impl<T: Serializer + ForyDefault> Serializer for Mutex<T> {
T::fory_reserved_space()
}
- fn fory_read(context: &mut ReadContext, is_field: bool) -> Result<Self, Error>
+ fn fory_read(fory: &Fory, context: &mut ReadContext, is_field: bool) -> Result<Self, Error>
where
Self: Sized + ForyDefault,
{
- Ok(Mutex::new(T::fory_read(context, is_field)?))
+ Ok(Mutex::new(T::fory_read(fory, context, is_field)?))
}
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
- Ok(Mutex::new(T::fory_read_data(context, is_field)?))
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
+ Ok(Mutex::new(T::fory_read_data(fory, context, is_field)?))
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- T::fory_read_type_info(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ T::fory_read_type_info(fory, context, is_field);
}
fn fory_get_type_id(fory: &Fory) -> u32 {
diff --git a/rust/fory-core/src/serializer/number.rs b/rust/fory-core/src/serializer/number.rs
index a830fc361..429afc4de 100644
--- a/rust/fory-core/src/serializer/number.rs
+++ b/rust/fory-core/src/serializer/number.rs
@@ -26,11 +26,15 @@ use crate::types::TypeId;
macro_rules! impl_num_serializer {
($ty:ty, $writer:expr, $reader:expr, $field_type:expr) => {
impl Serializer for $ty {
- fn fory_write_data(&self, context: &mut WriteContext, _is_field: bool) {
+ fn fory_write_data(&self, _fory: &Fory, context: &mut WriteContext, _is_field: bool) {
$writer(&mut context.writer, *self);
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ _fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
Ok($reader(&mut context.reader))
}
@@ -50,12 +54,12 @@ macro_rules! impl_num_serializer {
self
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- write_type_info::<Self>(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_type_info::<Self>(fory, context, is_field);
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- read_type_info::<Self>(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ read_type_info::<Self>(fory, context, is_field);
}
}
impl ForyDefault for $ty {
diff --git a/rust/fory-core/src/serializer/option.rs b/rust/fory-core/src/serializer/option.rs
index 8726c94b5..78211b16a 100644
--- a/rust/fory-core/src/serializer/option.rs
+++ b/rust/fory-core/src/serializer/option.rs
@@ -22,24 +22,28 @@ use crate::resolver::context::WriteContext;
use crate::serializer::{ForyDefault, Serializer};
impl<T: Serializer + ForyDefault> Serializer for Option<T> {
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
- Ok(Some(T::fory_read_data(context, is_field)?))
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
+ Ok(Some(T::fory_read_data(fory, context, is_field)?))
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- T::fory_read_type_info(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ T::fory_read_type_info(fory, context, is_field);
}
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
if let Some(v) = self {
- T::fory_write_data(v, context, is_field)
+ T::fory_write_data(v, fory, context, is_field)
} else {
unreachable!("write should be call by serialize")
}
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- T::fory_write_type_info(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ T::fory_write_type_info(fory, context, is_field);
}
fn fory_reserved_space() -> usize {
diff --git a/rust/fory-core/src/serializer/rc.rs b/rust/fory-core/src/serializer/rc.rs
index b0cafc96d..5d3c3716f 100644
--- a/rust/fory-core/src/serializer/rc.rs
+++ b/rust/fory-core/src/serializer/rc.rs
@@ -28,24 +28,27 @@ impl<T: Serializer + ForyDefault + 'static> Serializer for Rc<T> {
true
}
- fn fory_write(&self, context: &mut WriteContext, is_field: bool) {
- if !context.ref_writer.try_write_rc_ref(context.writer, self) {
- T::fory_write_data(self.as_ref(), context, is_field);
+ fn fory_write(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ if !context
+ .ref_writer
+ .try_write_rc_ref(&mut context.writer, self)
+ {
+ T::fory_write_data(self.as_ref(), fory, context, is_field);
}
}
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
// When Rc is nested inside another shared ref (like Arc<Rc<T>>),
// the outer ref calls fory_write_data on the inner Rc.
// We still need to track the Rc's own references here.
- self.fory_write(context, is_field);
+ self.fory_write(fory, context, is_field);
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- T::fory_write_type_info(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ T::fory_write_type_info(fory, context, is_field);
}
- fn fory_read(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
+ fn fory_read(fory: &Fory, context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader);
match ref_flag {
@@ -58,12 +61,12 @@ impl<T: Serializer + ForyDefault + 'static> Serializer for Rc<T> {
.ok_or_else(|| anyhow!("Rc reference {} not found", ref_id).into())
}
RefFlag::NotNullValue => {
- let inner = T::fory_read_data(context, is_field)?;
+ let inner = T::fory_read_data(fory, context, is_field)?;
Ok(Rc::new(inner))
}
RefFlag::RefValue => {
let ref_id = context.ref_reader.reserve_ref_id();
- let inner = T::fory_read_data(context, is_field)?;
+ let inner = T::fory_read_data(fory, context, is_field)?;
let rc = Rc::new(inner);
context.ref_reader.store_rc_ref_at(ref_id, rc.clone());
Ok(rc)
@@ -71,14 +74,18 @@ impl<T: Serializer + ForyDefault + 'static> Serializer for Rc<T> {
}
}
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
// When Rc is nested inside another shared ref, fory_read_data is called.
// Delegate to fory_read which handles ref tracking properly.
- Self::fory_read(context, is_field)
+ Self::fory_read(fory, context, is_field)
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- T::fory_read_type_info(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ T::fory_read_type_info(fory, context, is_field);
}
fn fory_reserved_space() -> usize {
diff --git a/rust/fory-core/src/serializer/refcell.rs b/rust/fory-core/src/serializer/refcell.rs
index f10978c34..9fff58be7 100644
--- a/rust/fory-core/src/serializer/refcell.rs
+++ b/rust/fory-core/src/serializer/refcell.rs
@@ -43,34 +43,38 @@ use std::cell::RefCell;
/// Simply delegates to the serializer for `T`, allowing interior mutable
/// containers to be included in serialized graphs.
impl<T: Serializer + ForyDefault> Serializer for RefCell<T> {
- fn fory_read(context: &mut ReadContext, is_field: bool) -> Result<Self, Error>
+ fn fory_read(fory: &Fory, context: &mut ReadContext, is_field: bool) -> Result<Self, Error>
where
Self: Sized + ForyDefault,
{
- Ok(RefCell::new(T::fory_read(context, is_field)?))
+ Ok(RefCell::new(T::fory_read(fory, context, is_field)?))
}
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
- Ok(RefCell::new(T::fory_read_data(context, is_field)?))
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
+ Ok(RefCell::new(T::fory_read_data(fory, context, is_field)?))
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- T::fory_read_type_info(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ T::fory_read_type_info(fory, context, is_field);
}
- fn fory_write(&self, context: &mut WriteContext, is_field: bool) {
+ fn fory_write(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
// Don't add ref tracking for RefCell itself, just delegate to inner type
// The inner type will handle its own ref tracking
- T::fory_write(&*self.borrow(), context, is_field);
+ T::fory_write(&*self.borrow(), fory, context, is_field);
}
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
// When called from Rc, just delegate to inner type's data serialization
- T::fory_write_data(&*self.borrow(), context, is_field)
+ T::fory_write_data(&*self.borrow(), fory, context, is_field)
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- T::fory_write_type_info(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ T::fory_write_type_info(fory, context, is_field);
}
fn fory_reserved_space() -> usize {
diff --git a/rust/fory-core/src/serializer/set.rs b/rust/fory-core/src/serializer/set.rs
index 47ebe0b0b..7755cbaf7 100644
--- a/rust/fory-core/src/serializer/set.rs
+++ b/rust/fory-core/src/serializer/set.rs
@@ -29,19 +29,23 @@ use std::collections::{BTreeSet, HashSet};
use std::mem;
impl<T: Serializer + ForyDefault + Eq + std::hash::Hash> Serializer for HashSet<T> {
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- write_collection(self, context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_collection(self, fory, context, is_field);
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
+ fn fory_write_type_info(_fory: &Fory, context: &mut WriteContext, is_field: bool) {
write_collection_type_info(context, is_field, TypeId::SET as u32);
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
- read_collection(context)
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
+ read_collection(fory, context)
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
+ fn fory_read_type_info(_fory: &Fory, context: &mut ReadContext, is_field: bool) {
read_collection_type_info(context, is_field, TypeId::SET as u32)
}
@@ -69,19 +73,23 @@ impl<T> ForyDefault for HashSet<T> {
}
impl<T: Serializer + ForyDefault + Ord> Serializer for BTreeSet<T> {
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- write_collection(self, context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_collection(self, fory, context, is_field);
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
+ fn fory_write_type_info(_fory: &Fory, context: &mut WriteContext, is_field: bool) {
write_collection_type_info(context, is_field, TypeId::SET as u32);
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
- read_collection(context)
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
+ read_collection(fory, context)
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
+ fn fory_read_type_info(_fory: &Fory, context: &mut ReadContext, is_field: bool) {
read_collection_type_info(context, is_field, TypeId::SET as u32)
}
diff --git a/rust/fory-core/src/serializer/skip.rs b/rust/fory-core/src/serializer/skip.rs
index c1538dbfe..dda7ff175 100644
--- a/rust/fory-core/src/serializer/skip.rs
+++ b/rust/fory-core/src/serializer/skip.rs
@@ -21,6 +21,7 @@ use crate::resolver::context::ReadContext;
use crate::serializer::collection::{HAS_NULL, IS_SAME_TYPE};
use crate::serializer::Serializer;
use crate::types::{RefFlag, TypeId, BASIC_TYPES, CONTAINER_TYPES, PRIMITIVE_TYPES};
+use crate::Fory;
use chrono::{NaiveDate, NaiveDateTime};
pub fn get_read_ref_flag(field_type: &NullableFieldType) -> bool {
@@ -29,11 +30,11 @@ pub fn get_read_ref_flag(field_type: &NullableFieldType) -> bool {
}
macro_rules! basic_type_deserialize {
- ($tid:expr, $context:expr; $(($ty:ty, $id:ident)),+ $(,)?) => {
+ ($fory:expr, $tid:expr, $context:expr; $(($ty:ty, $id:ident)),+ $(,)?) => {
$(
if $tid == TypeId::$id {
- <$ty as Serializer>::fory_read_type_info($context, true);
- <$ty as Serializer>::fory_read_data($context, true)?;
+ <$ty as Serializer>::fory_read_type_info($fory, $context, true);
+ <$ty as Serializer>::fory_read_data($fory, $context, true)?;
return Ok(());
}
)+else {
@@ -45,6 +46,7 @@ macro_rules! basic_type_deserialize {
// call when is_field && is_compatible_mode
#[allow(unreachable_code)]
pub fn skip_field_value(
+ fory: &Fory,
context: &mut ReadContext,
field_type: &NullableFieldType,
read_ref_flag: bool,
@@ -59,7 +61,7 @@ pub fn skip_field_value(
match TypeId::try_from(type_id_num as i16) {
Ok(type_id) => {
if BASIC_TYPES.contains(&type_id) {
- basic_type_deserialize!(type_id, context;
+ basic_type_deserialize!(fory, type_id, context;
(bool, BOOL),
(i8, INT8),
(i16, INT16),
@@ -91,7 +93,7 @@ pub fn skip_field_value(
let elem_type = field_type.generics.first().unwrap();
context.inc_depth()?;
for _ in 0..length {
- skip_field_value(context, elem_type, !skip_ref_flag)?;
+ skip_field_value(fory, context, elem_type, !skip_ref_flag)?;
}
context.dec_depth();
} else if type_id == TypeId::MAP {
@@ -116,7 +118,7 @@ pub fn skip_field_value(
if header & crate::serializer::map::KEY_NULL != 0 {
// let read_ref_flag = get_read_ref_flag(value_type);
context.inc_depth()?;
- skip_field_value(context, value_type, false)?;
+ skip_field_value(fory, context, value_type, false)?;
context.dec_depth();
len_counter += 1;
continue;
@@ -124,7 +126,7 @@ pub fn skip_field_value(
if header & crate::serializer::map::VALUE_NULL != 0 {
// let read_ref_flag = get_read_ref_flag(key_type);
context.inc_depth()?;
- skip_field_value(context, key_type, false)?;
+ skip_field_value(fory, context, key_type, false)?;
context.dec_depth();
len_counter += 1;
continue;
@@ -133,9 +135,9 @@ pub fn skip_field_value(
context.inc_depth()?;
for _ in (0..chunk_size).enumerate() {
// let read_ref_flag = get_read_ref_flag(key_type);
- skip_field_value(context, key_type, false)?;
+ skip_field_value(fory, context, key_type, false)?;
// let read_ref_flag = get_read_ref_flag(value_type);
- skip_field_value(context, value_type, false)?;
+ skip_field_value(fory, context, value_type, false)?;
}
context.dec_depth();
len_counter += chunk_size as u32;
@@ -153,10 +155,9 @@ pub fn skip_field_value(
let field_infos = type_meta.get_field_infos().to_vec();
context.inc_depth()?;
for field_info in field_infos.iter() {
- let nullable_field_type =
- NullableFieldType::from(field_info.field_type.clone());
+ let nullable_field_type = NullableFieldType::from(&field_info.field_type);
let read_ref_flag = get_read_ref_flag(&nullable_field_type);
- skip_field_value(context, &nullable_field_type, read_ref_flag)?;
+ skip_field_value(fory, context, &nullable_field_type, read_ref_flag)?;
}
context.dec_depth();
Ok(())
@@ -165,10 +166,10 @@ pub fn skip_field_value(
assert_eq!(type_id_num, remote_type_id);
let meta_index = context.reader.read_varuint32();
let type_meta = context.get_meta(meta_index as usize);
- let type_resolver = context.get_fory().get_type_resolver();
+ let type_resolver = fory.get_type_resolver();
type_resolver
.get_ext_name_harness(&type_meta.get_namespace(), &type_meta.get_type_name())
- .get_read_data_fn()(context, true)?;
+ .get_read_data_fn()(fory, context, true)?;
Ok(())
} else {
unreachable!("unimplemented type: {:?}", type_id);
@@ -187,10 +188,9 @@ pub fn skip_field_value(
let field_infos = type_meta.get_field_infos().to_vec();
context.inc_depth()?;
for field_info in field_infos.iter() {
- let nullable_field_type =
- NullableFieldType::from(field_info.field_type.clone());
+ let nullable_field_type = NullableFieldType::from(&field_info.field_type);
let read_ref_flag = get_read_ref_flag(&nullable_field_type);
- skip_field_value(context, &nullable_field_type, read_ref_flag)?;
+ skip_field_value(fory, context, &nullable_field_type, read_ref_flag)?;
}
context.dec_depth();
} else if internal_id == ENUM_ID {
@@ -199,10 +199,10 @@ pub fn skip_field_value(
let remote_type_id = context.reader.read_varuint32();
assert_eq!(remote_type_id, type_id_num);
context.inc_depth()?;
- let type_resolver = context.get_fory().get_type_resolver();
+ let type_resolver = fory.get_type_resolver();
type_resolver
.get_ext_harness(type_id_num)
- .get_read_data_fn()(context, true)?;
+ .get_read_data_fn()(fory, context, true)?;
context.dec_depth();
} else {
unreachable!("unimplemented skipped type: {:?}", type_id_num);
diff --git a/rust/fory-core/src/serializer/string.rs b/rust/fory-core/src/serializer/string.rs
index 65c2eb77b..9fb68d69b 100644
--- a/rust/fory-core/src/serializer/string.rs
+++ b/rust/fory-core/src/serializer/string.rs
@@ -31,13 +31,13 @@ enum StrEncoding {
}
impl Serializer for String {
- fn fory_write_data(&self, context: &mut WriteContext, _is_field: bool) {
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, _is_field: bool) {
let mut len = get_latin1_length(self);
if len >= 0 {
let bitor = (len as u64) << 2 | StrEncoding::Latin1 as u64;
context.writer.write_varuint36_small(bitor);
context.writer.write_latin1_string(self);
- } else if context.get_fory().is_compress_string() {
+ } else if fory.is_compress_string() {
// todo: support `writeNumUtf16BytesForUtf8Encoding` like in java
len = self.len() as i32;
let bitor = (len as u64) << 2 | StrEncoding::Utf8 as u64;
@@ -51,7 +51,11 @@ impl Serializer for String {
}
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ _fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
let bitor = context.reader.read_varuint36small();
let len = bitor >> 2;
let encoding = bitor & 0b11;
@@ -87,12 +91,12 @@ impl Serializer for String {
self
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- write_type_info::<Self>(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_type_info::<Self>(fory, context, is_field);
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- read_type_info::<Self>(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ read_type_info::<Self>(fory, context, is_field);
}
}
diff --git a/rust/fory-core/src/serializer/struct_.rs b/rust/fory-core/src/serializer/struct_.rs
index b8b553c72..a171d1859 100644
--- a/rust/fory-core/src/serializer/struct_.rs
+++ b/rust/fory-core/src/serializer/struct_.rs
@@ -43,14 +43,21 @@ pub fn type_def<T: Serializer + StructSerializer>(
namespace: MetaString,
type_name: MetaString,
register_by_name: bool,
- field_infos: &[FieldInfo],
+ mut field_infos: Vec<FieldInfo>,
) -> Vec<u8> {
let sorted_field_names = T::fory_get_sorted_field_names(fory);
- let mut sorted_field_infos = Vec::with_capacity(field_infos.len());
- for name in &sorted_field_names {
- if let Some(info) = field_infos.iter().find(|f| &f.field_name == name) {
- sorted_field_infos.push(info.clone());
- } else {
+ let mut sorted_field_infos: Vec<FieldInfo> = Vec::with_capacity(field_infos.len());
+ for name in sorted_field_names.iter() {
+ let mut found = false;
+ for i in 0..field_infos.len() {
+ if &field_infos[i].field_name == name {
+ // swap_remove is faster
+ sorted_field_infos.push(field_infos.swap_remove(i));
+ found = true;
+ break;
+ }
+ }
+ if !found {
panic!("Field {} not found in field_infos", name);
}
}
@@ -65,51 +72,42 @@ pub fn type_def<T: Serializer + StructSerializer>(
}
#[inline(always)]
-pub fn write_type_info<T: Serializer>(context: &mut WriteContext, _is_field: bool) {
- let type_id = T::fory_get_type_id(context.get_fory());
+pub fn write_type_info<T: Serializer>(fory: &Fory, context: &mut WriteContext, _is_field: bool) {
+ let type_id = T::fory_get_type_id(fory);
context.writer.write_varuint32(type_id);
let rs_type_id = std::any::TypeId::of::<T>();
if type_id & 0xff == TypeId::NAMED_STRUCT as u32 {
- if context.get_fory().is_share_meta() {
- let meta_index = context.push_meta(rs_type_id) as u32;
+ if fory.is_share_meta() {
+ let meta_index = context.push_meta(fory, rs_type_id) as u32;
context.writer.write_varuint32(meta_index);
} else {
- let type_info = context
- .get_fory()
- .get_type_resolver()
- .get_type_info(rs_type_id);
+ let type_info = fory.get_type_resolver().get_type_info(rs_type_id);
let namespace = type_info.get_namespace().to_owned();
let type_name = type_info.get_type_name().to_owned();
- let resolver = context.get_fory().get_metastring_resolver();
- resolver
- .borrow_mut()
- .write_meta_string_bytes(context, &namespace);
- resolver
- .borrow_mut()
- .write_meta_string_bytes(context, &type_name);
+ context.write_meta_string_bytes(&namespace);
+ context.write_meta_string_bytes(&type_name);
}
} else if type_id & 0xff == TypeId::NAMED_COMPATIBLE_STRUCT as u32
|| type_id & 0xff == TypeId::COMPATIBLE_STRUCT as u32
{
- let meta_index = context.push_meta(rs_type_id) as u32;
+ let meta_index = context.push_meta(fory, rs_type_id) as u32;
context.writer.write_varuint32(meta_index);
}
}
#[inline(always)]
-pub fn read_type_info<T: Serializer>(context: &mut ReadContext, _is_field: bool) {
+pub fn read_type_info<T: Serializer>(fory: &Fory, context: &mut ReadContext, _is_field: bool) {
let remote_type_id = context.reader.read_varuint32();
- let local_type_id = T::fory_get_type_id(context.get_fory());
+ let local_type_id = T::fory_get_type_id(fory);
assert_eq!(remote_type_id, local_type_id);
if local_type_id & 0xff == TypeId::NAMED_STRUCT as u32 {
- if context.get_fory().is_share_meta() {
+ if fory.is_share_meta() {
let _meta_index = context.reader.read_varuint32();
} else {
- let resolver = context.get_fory().get_metastring_resolver();
- resolver.borrow_mut().read_meta_string_bytes(context);
- resolver.borrow_mut().read_meta_string_bytes(context);
+ let _namespace_msb = context.read_meta_string_bytes();
+ let _type_name_msb = context.read_meta_string_bytes();
}
} else if local_type_id & 0xff == TypeId::NAMED_COMPATIBLE_STRUCT as u32
|| local_type_id & 0xff == TypeId::COMPATIBLE_STRUCT as u32
@@ -119,18 +117,18 @@ pub fn read_type_info<T: Serializer>(context: &mut ReadContext, _is_field: bool)
}
#[inline(always)]
-pub fn write<T: Serializer>(this: &T, context: &mut WriteContext, _is_field: bool) {
- match context.get_fory().get_mode() {
+pub fn write<T: Serializer>(this: &T, fory: &Fory, context: &mut WriteContext, _is_field: bool) {
+ match fory.get_mode() {
// currently same
Mode::SchemaConsistent => {
context.writer.write_i8(RefFlag::NotNullValue as i8);
- T::fory_write_type_info(context, false);
- this.fory_write_data(context, true);
+ T::fory_write_type_info(fory, context, false);
+ this.fory_write_data(fory, context, true);
}
Mode::Compatible => {
context.writer.write_i8(RefFlag::NotNullValue as i8);
- T::fory_write_type_info(context, false);
- this.fory_write_data(context, true);
+ T::fory_write_type_info(fory, context, false);
+ this.fory_write_data(fory, context, true);
}
}
}
diff --git a/rust/fory-core/src/serializer/trait_object.rs b/rust/fory-core/src/serializer/trait_object.rs
index d4ce4c39a..29ea1a7bd 100644
--- a/rust/fory-core/src/serializer/trait_object.rs
+++ b/rust/fory-core/src/serializer/trait_object.rs
@@ -24,6 +24,7 @@ use crate::serializer::{ForyDefault, Serializer};
///
/// Writes common trait object headers (ref flag, type ID, compatibility metadata)
pub fn write_trait_object_headers(
+ fory: &Fory,
context: &mut WriteContext,
fory_type_id: u32,
concrete_type_id: std::any::TypeId,
@@ -33,17 +34,17 @@ pub fn write_trait_object_headers(
context.writer.write_i8(RefFlag::NotNullValue as i8);
context.writer.write_varuint32(fory_type_id);
- if context.get_fory().get_mode() == &Mode::Compatible
+ if fory.get_mode() == &Mode::Compatible
&& (fory_type_id & 0xff == TypeId::NAMED_COMPATIBLE_STRUCT as u32
|| fory_type_id & 0xff == TypeId::COMPATIBLE_STRUCT as u32)
{
- let meta_index = context.push_meta(concrete_type_id) as u32;
+ let meta_index = context.push_meta(fory, concrete_type_id) as u32;
context.writer.write_varuint32(meta_index);
}
}
/// Reads common trait object headers and returns the type ID
-pub fn read_trait_object_headers(context: &mut ReadContext) -> Result<u32, Error> {
+pub fn read_trait_object_headers(fory: &Fory, context: &mut ReadContext) -> Result<u32, Error> {
use crate::types::{Mode, RefFlag, TypeId};
let ref_flag = context.reader.read_i8();
@@ -56,7 +57,7 @@ pub fn read_trait_object_headers(context: &mut ReadContext) -> Result<u32, Error
let fory_type_id = context.reader.read_varuint32();
- if context.get_fory().get_mode() == &Mode::Compatible
+ if fory.get_mode() == &Mode::Compatible
&& (fory_type_id & 0xff == TypeId::NAMED_COMPATIBLE_STRUCT as u32
|| fory_type_id & 0xff == TypeId::COMPATIBLE_STRUCT as u32)
{
@@ -69,11 +70,11 @@ pub fn read_trait_object_headers(context: &mut ReadContext) -> Result<u32, Error
/// Helper macro for common type resolution and downcasting pattern
#[macro_export]
macro_rules! downcast_and_serialize {
- ($any_ref:expr, $context:expr, $is_field:expr, $trait_name:ident, $($impl_type:ty),+) => {{
+ ($any_ref:expr, $fory:expr, $context:expr, $is_field:expr, $trait_name:ident, $($impl_type:ty),+) => {{
$(
if $any_ref.type_id() == std::any::TypeId::of::<$impl_type>() {
if let Some(concrete) = $any_ref.downcast_ref::<$impl_type>() {
- concrete.fory_write_data($context, $is_field);
+ concrete.fory_write_data($fory, $context, $is_field);
return;
}
}
@@ -85,11 +86,11 @@ macro_rules! downcast_and_serialize {
/// Helper macro for common type resolution and deserialization pattern
#[macro_export]
macro_rules! resolve_and_deserialize {
- ($fory_type_id:expr, $context:expr, $is_field:expr, $constructor:expr, $trait_name:ident, $($impl_type:ty),+) => {{
+ ($fory_type_id:expr, $fory:expr, $context:expr, $is_field:expr, $constructor:expr, $trait_name:ident, $($impl_type:ty),+) => {{
$(
- if let Some(registered_type_id) = $context.get_fory().get_type_resolver().get_fory_type_id(std::any::TypeId::of::<$impl_type>()) {
+ if let Some(registered_type_id) = $fory.get_type_resolver().get_fory_type_id(std::any::TypeId::of::<$impl_type>()) {
if $fory_type_id == registered_type_id {
- let concrete_obj = <$impl_type as $crate::serializer::Serializer>::fory_read_data($context, $is_field)?;
+ let concrete_obj = <$impl_type as $crate::serializer::Serializer>::fory_read_data($fory, $context, $is_field)?;
return Ok($constructor(concrete_obj));
}
}
@@ -200,21 +201,21 @@ macro_rules! register_trait_type {
// 4. Serializer implementation for Box<dyn Trait> (existing functionality)
impl $crate::serializer::Serializer for Box<dyn $trait_name> {
- fn fory_write(&self, context: &mut $crate::resolver::context::WriteContext, is_field: bool) {
+ fn fory_write(&self, fory: &$crate::fory::Fory, context: &mut $crate::resolver::context::WriteContext, is_field: bool) {
let any_ref = <dyn $trait_name as $crate::serializer::Serializer>::as_any(&**self);
let concrete_type_id = any_ref.type_id();
- if let Some(fory_type_id) = context.get_fory().get_type_resolver().get_fory_type_id(concrete_type_id) {
- $crate::serializer::trait_object::write_trait_object_headers(context, fory_type_id, concrete_type_id);
- $crate::downcast_and_serialize!(any_ref, context, is_field, $trait_name, $($impl_type),+);
+ if let Some(fory_type_id) = fory.get_type_resolver().get_fory_type_id(concrete_type_id) {
+ $crate::serializer::trait_object::write_trait_object_headers(fory, context, fory_type_id, concrete_type_id);
+ $crate::downcast_and_serialize!(any_ref, fory, context, is_field, $trait_name, $($impl_type),+);
} else {
panic!("Type {:?} not registered for Box<dyn {}> serialization", concrete_type_id, stringify!($trait_name));
}
}
- fn fory_write_data(&self, context: &mut $crate::resolver::context::WriteContext, is_field: bool) {
+ fn fory_write_data(&self, fory: &$crate::fory::Fory, context: &mut $crate::resolver::context::WriteContext, is_field: bool) {
// Delegate to fory_write since this handles the polymorphic dispatch
- self.fory_write(context, is_field);
+ self.fory_write(fory, context, is_field);
}
fn fory_type_id_dyn(&self, fory: &$crate::fory::Fory) -> u32 {
@@ -229,19 +230,19 @@ macro_rules! register_trait_type {
true
}
- fn fory_write_type_info(_context: &mut $crate::resolver::context::WriteContext, _is_field: bool) {
+ fn fory_write_type_info(fory: &$crate::fory::Fory, _context: &mut $crate::resolver::context::WriteContext, _is_field: bool) {
// Box<dyn Trait> is polymorphic - type info is written per element
}
- fn fory_read_type_info(_context: &mut $crate::resolver::context::ReadContext, _is_field: bool) {
+ fn fory_read_type_info(fory: &$crate::fory::Fory, _context: &mut $crate::resolver::context::ReadContext, _is_field: bool) {
// Box<dyn Trait> is polymorphic - type info is read per element
}
- fn fory_read(context: &mut $crate::resolver::context::ReadContext, is_field: bool) -> Result<Self, $crate::error::Error> {
+ fn fory_read(fory: &$crate::fory::Fory, context: &mut $crate::resolver::context::ReadContext, is_field: bool) -> Result<Self, $crate::error::Error> {
context.inc_depth()?;
- let fory_type_id = $crate::serializer::trait_object::read_trait_object_headers(context)?;
+ let fory_type_id = $crate::serializer::trait_object::read_trait_object_headers(fory, context)?;
let result = $crate::resolve_and_deserialize!(
- fory_type_id, context, is_field,
+ fory_type_id, fory, context, is_field,
|obj| Box::new(obj) as Box<dyn $trait_name>,
$trait_name, $($impl_type),+
);
@@ -249,7 +250,7 @@ macro_rules! register_trait_type {
result
}
- fn fory_read_data(_context: &mut $crate::resolver::context::ReadContext, _is_field: bool) -> Result<Self, $crate::error::Error> {
+ fn fory_read_data(fory: &$crate::fory::Fory, _context: &mut $crate::resolver::context::ReadContext, _is_field: bool) -> Result<Self, $crate::error::Error> {
// This should not be called for polymorphic types like Box<dyn Trait>
// The fory_read method handles the polymorphic dispatch
panic!("fory_read_data should not be called directly on polymorphic Box<dyn {}> trait object", stringify!($trait_name));
@@ -404,22 +405,22 @@ macro_rules! generate_smart_pointer_wrapper {
macro_rules! impl_smart_pointer_serializer {
($wrapper_name:ident, $pointer_type:ty, $constructor_expr:expr, $trait_name:ident, $try_write_ref:ident, $get_ref:ident, $store_ref:ident, $($impl_type:ty),+) => {
impl $crate::serializer::Serializer for $wrapper_name {
- fn fory_write(&self, context: &mut $crate::resolver::context::WriteContext, is_field: bool) {
- if !context.ref_writer.$try_write_ref(context.writer, &self.0) {
+ fn fory_write(&self, fory: &$crate::fory::Fory, context: &mut $crate::resolver::context::WriteContext, is_field: bool) {
+ if !context.ref_writer.$try_write_ref(&mut context.writer, &self.0) {
let any_obj = <dyn $trait_name as $crate::serializer::Serializer>::as_any(&*self.0);
let concrete_type_id = any_obj.type_id();
- let harness = context.write_any_typeinfo(concrete_type_id);
+ let harness = context.write_any_typeinfo(fory, concrete_type_id);
let serializer_fn = harness.get_write_data_fn();
- serializer_fn(any_obj, context, is_field);
+ serializer_fn(any_obj, fory, context, is_field);
}
}
- fn fory_write_data(&self, context: &mut $crate::resolver::context::WriteContext, is_field: bool) {
+ fn fory_write_data(&self, fory: &$crate::fory::Fory, context: &mut $crate::resolver::context::WriteContext, is_field: bool) {
let any_obj = <dyn $trait_name as $crate::serializer::Serializer>::as_any(&*self.0);
- $crate::downcast_and_serialize!(any_obj, context, is_field, $trait_name, $($impl_type),+);
+ $crate::downcast_and_serialize!(any_obj, fory, context, is_field, $trait_name, $($impl_type),+);
}
- fn fory_read(context: &mut $crate::resolver::context::ReadContext, is_field: bool) -> Result<Self, $crate::error::Error> {
+ fn fory_read(fory: &$crate::fory::Fory, context: &mut $crate::resolver::context::ReadContext, is_field: bool) -> Result<Self, $crate::error::Error> {
use $crate::types::RefFlag;
let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader);
@@ -438,9 +439,9 @@ macro_rules! impl_smart_pointer_serializer {
}
RefFlag::NotNullValue => {
context.inc_depth()?;
- let harness = context.read_any_typeinfo();
+ let harness = context.read_any_typeinfo(fory);
let deserializer_fn = harness.get_read_data_fn();
- let boxed_any = deserializer_fn(context, is_field)?;
+ let boxed_any = deserializer_fn(fory, context, is_field)?;
context.dec_depth();
$(
@@ -458,9 +459,9 @@ macro_rules! impl_smart_pointer_serializer {
}
RefFlag::RefValue => {
context.inc_depth()?;
- let harness = context.read_any_typeinfo();
+ let harness = context.read_any_typeinfo(fory);
let deserializer_fn = harness.get_read_data_fn();
- let boxed_any = deserializer_fn(context, is_field)?;
+ let boxed_any = deserializer_fn(fory, context, is_field)?;
context.dec_depth();
$(
@@ -479,10 +480,10 @@ macro_rules! impl_smart_pointer_serializer {
}
}
}
- fn fory_read_data(context: &mut $crate::resolver::context::ReadContext, is_field: bool) -> Result<Self, $crate::error::Error> {
+ fn fory_read_data(fory: &$crate::fory::Fory, context: &mut $crate::resolver::context::ReadContext, is_field: bool) -> Result<Self, $crate::error::Error> {
let concrete_fory_type_id = context.reader.read_varuint32();
$crate::resolve_and_deserialize!(
- concrete_fory_type_id, context, is_field,
+ concrete_fory_type_id, fory, context, is_field,
|obj| {
let pointer = $constructor_expr(obj) as $pointer_type;
Self::from(pointer)
@@ -495,10 +496,10 @@ macro_rules! impl_smart_pointer_serializer {
$crate::types::TypeId::STRUCT as u32
}
- fn fory_write_type_info(_context: &mut $crate::resolver::context::WriteContext, _is_field: bool) {
+ fn fory_write_type_info(_fory: &$crate::fory::Fory, _context: &mut $crate::resolver::context::WriteContext, _is_field: bool) {
}
- fn fory_read_type_info(_context: &mut $crate::resolver::context::ReadContext, _is_field: bool) {
+ fn fory_read_type_info(fory: &$crate::fory::Fory, _context: &mut $crate::resolver::context::ReadContext, _is_field: bool) {
}
fn fory_is_polymorphic() -> bool {
@@ -538,15 +539,15 @@ impl ForyDefault for Box<dyn Serializer> {
}
impl Serializer for Box<dyn Serializer> {
- fn fory_write(&self, context: &mut WriteContext, is_field: bool) {
- let fory_type_id = (**self).fory_type_id_dyn(context.get_fory());
+ fn fory_write(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ let fory_type_id = (**self).fory_type_id_dyn(fory);
let concrete_type_id = (**self).fory_concrete_type_id();
- write_trait_object_headers(context, fory_type_id, concrete_type_id);
- (**self).fory_write_data(context, is_field);
+ write_trait_object_headers(fory, context, fory_type_id, concrete_type_id);
+ (**self).fory_write_data(fory, context, is_field);
}
- fn fory_write_data(&self, _context: &mut WriteContext, _is_field: bool) {
+ fn fory_write_data(&self, _fory: &Fory, _context: &mut WriteContext, _is_field: bool) {
panic!("fory_write_data should not be called directly on Box<dyn Serializer>");
}
@@ -562,23 +563,23 @@ impl Serializer for Box<dyn Serializer> {
true
}
- fn fory_write_type_info(_context: &mut WriteContext, _is_field: bool) {
+ fn fory_write_type_info(_fory: &Fory, _context: &mut WriteContext, _is_field: bool) {
// Box<dyn Serializer> is polymorphic - type info is written per element
}
- fn fory_read_type_info(_context: &mut ReadContext, _is_field: bool) {
+ fn fory_read_type_info(_fory: &Fory, _context: &mut ReadContext, _is_field: bool) {
// Box<dyn Serializer> is polymorphic - type info is read per element
}
- fn fory_read(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
- let fory_type_id = read_trait_object_headers(context)?;
+ fn fory_read(fory: &Fory, context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
+ let fory_type_id = read_trait_object_headers(fory, context)?;
context.inc_depth()?;
- let type_resolver = context.get_fory().get_type_resolver();
+ let type_resolver = fory.get_type_resolver();
if let Some(harness) = type_resolver.get_harness(fory_type_id) {
let deserializer_fn = harness.get_read_fn();
let to_serializer_fn = harness.get_to_serializer();
- let boxed_any = deserializer_fn(context, is_field, true)?;
+ let boxed_any = deserializer_fn(fory, context, is_field, true)?;
let trait_object = to_serializer_fn(boxed_any)?;
context.dec_depth();
Ok(trait_object)
@@ -613,7 +614,11 @@ impl Serializer for Box<dyn Serializer> {
}
}
}
- fn fory_read_data(_context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ _fory: &Fory,
+ _context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
panic!("fory_read_data should not be called directly on Box<dyn Serializer>");
}
}
diff --git a/rust/fory-core/src/serializer/weak.rs b/rust/fory-core/src/serializer/weak.rs
index 57b722e37..f0c8e3fba 100644
--- a/rust/fory-core/src/serializer/weak.rs
+++ b/rust/fory-core/src/serializer/weak.rs
@@ -313,33 +313,36 @@ impl<T: Serializer + ForyDefault + 'static> Serializer for RcWeak<T> {
true
}
- fn fory_write(&self, context: &mut WriteContext, _is_field: bool) {
+ fn fory_write(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
if let Some(rc) = self.upgrade() {
- if context.ref_writer.try_write_rc_ref(context.writer, &rc) {
+ if context
+ .ref_writer
+ .try_write_rc_ref(&mut context.writer, &rc)
+ {
return;
}
- T::fory_write_data(&*rc, context, _is_field);
+ T::fory_write_data(&*rc, fory, context, is_field);
} else {
context.writer.write_i8(RefFlag::Null as i8);
}
}
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- self.fory_write(context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ self.fory_write(fory, context, is_field);
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- T::fory_write_type_info(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ T::fory_write_type_info(fory, context, is_field);
}
- fn fory_read(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read(fory: &Fory, context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader);
match ref_flag {
RefFlag::Null => Ok(RcWeak::new()),
RefFlag::RefValue => {
context.inc_depth()?;
- let data = T::fory_read_data(context, _is_field)?;
+ let data = T::fory_read_data(fory, context, is_field)?;
context.dec_depth();
let rc = Rc::new(data);
let ref_id = context.ref_reader.store_rc_ref(rc);
@@ -368,12 +371,16 @@ impl<T: Serializer + ForyDefault + 'static> Serializer for RcWeak<T> {
}
}
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
- Self::fory_read(context, is_field)
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
+ Self::fory_read(fory, context, is_field)
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- T::fory_read_type_info(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ T::fory_read_type_info(fory, context, is_field);
}
fn fory_reserved_space() -> usize {
@@ -409,36 +416,39 @@ impl<T: Serializer + ForyDefault + Send + Sync + 'static> Serializer for ArcWeak
true
}
- fn fory_write(&self, context: &mut WriteContext, _is_field: bool) {
+ fn fory_write(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
if let Some(arc) = self.upgrade() {
// IMPORTANT: If the target Arc was serialized already, just write a ref
- if context.ref_writer.try_write_arc_ref(context.writer, &arc) {
+ if context
+ .ref_writer
+ .try_write_arc_ref(&mut context.writer, &arc)
+ {
// Already seen, wrote Ref flag + id, we're done
return;
}
// First time seeing this object, write RefValue and then its data
- T::fory_write_data(&*arc, context, _is_field);
+ T::fory_write_data(&*arc, fory, context, is_field);
} else {
context.writer.write_i8(RefFlag::Null as i8);
}
}
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- self.fory_write(context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ self.fory_write(fory, context, is_field);
}
- fn fory_write_type_info(context: &mut WriteContext, is_field: bool) {
- T::fory_write_type_info(context, is_field);
+ fn fory_write_type_info(fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ T::fory_write_type_info(fory, context, is_field);
}
- fn fory_read(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read(fory: &Fory, context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader);
match ref_flag {
RefFlag::Null => Ok(ArcWeak::new()),
RefFlag::RefValue => {
context.inc_depth()?;
- let data = T::fory_read_data(context, _is_field)?;
+ let data = T::fory_read_data(fory, context, _is_field)?;
context.dec_depth();
let arc = Arc::new(data);
let ref_id = context.ref_reader.store_arc_ref(arc);
@@ -469,12 +479,16 @@ impl<T: Serializer + ForyDefault + Send + Sync + 'static> Serializer for ArcWeak
_ => Err(anyhow!("Weak can only be Null, RefValue or Ref, got {:?}", ref_flag).into()),
}
}
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
- Self::fory_read(context, is_field)
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
+ Self::fory_read(fory, context, is_field)
}
- fn fory_read_type_info(context: &mut ReadContext, is_field: bool) {
- T::fory_read_type_info(context, is_field);
+ fn fory_read_type_info(fory: &Fory, context: &mut ReadContext, is_field: bool) {
+ T::fory_read_type_info(fory, context, is_field);
}
fn fory_reserved_space() -> usize {
diff --git a/rust/fory-derive/src/object/derive_enum.rs b/rust/fory-derive/src/object/derive_enum.rs
index 876a97c8e..df35fdd4a 100644
--- a/rust/fory-derive/src/object/derive_enum.rs
+++ b/rust/fory-derive/src/object/derive_enum.rs
@@ -39,13 +39,13 @@ pub fn gen_reserved_space() -> TokenStream {
pub fn gen_write_type_info() -> TokenStream {
quote! {
- fory_core::serializer::enum_::write_type_info::<Self>(context, is_field)
+ fory_core::serializer::enum_::write_type_info::<Self>(fory, context, is_field)
}
}
pub fn gen_read_type_info() -> TokenStream {
quote! {
- fory_core::serializer::enum_::read_type_info::<Self>(context, is_field)
+ fory_core::serializer::enum_::read_type_info::<Self>(fory, context, is_field)
}
}
@@ -79,18 +79,18 @@ pub fn gen_read_data(data_enum: &DataEnum) -> TokenStream {
pub fn gen_read_compatible() -> TokenStream {
quote! {
- fory_core::serializer::enum_::read_compatible::<Self>(context)
+ fory_core::serializer::enum_::read_compatible::<Self>(fory, context)
}
}
pub fn gen_write(_data_enum: &DataEnum) -> TokenStream {
quote! {
- fory_core::serializer::enum_::write::<Self>(self, context, is_field)
+ fory_core::serializer::enum_::write::<Self>(self, fory, context, is_field)
}
}
pub fn gen_read(_data_enum: &DataEnum) -> TokenStream {
quote! {
- fory_core::serializer::enum_::read::<Self>(context, is_field)
+ fory_core::serializer::enum_::read::<Self>(fory, context, is_field)
}
}
diff --git a/rust/fory-derive/src/object/misc.rs b/rust/fory-derive/src/object/misc.rs
index ec05f0f4c..80fedeb20 100644
--- a/rust/fory-derive/src/object/misc.rs
+++ b/rust/fory-derive/src/object/misc.rs
@@ -71,8 +71,9 @@ pub fn gen_get_sorted_field_names(fields: &[&Field]) -> TokenStream {
Some(result) => result,
None => {
#create_sorted_field_names
- fory.get_type_resolver().set_sorted_field_names::<Self>(&sorted_field_names);
- sorted_field_names
+ let arc_sorted_field_names = std::sync::Arc::new(sorted_field_names);
+ fory.get_type_resolver().set_sorted_field_names::<Self>(arc_sorted_field_names.clone());
+ arc_sorted_field_names
}
};
sorted_field_names
@@ -86,7 +87,7 @@ pub fn gen_type_def(fields: &[&Field]) -> TokenStream {
match classify_trait_object_field(ty) {
StructField::None => {
let generic_tree = parse_generic_tree(ty);
- let generic_token = generic_tree_to_tokens(&generic_tree, false);
+ let generic_token = generic_tree_to_tokens(&generic_tree);
quote! {
fory_core::meta::FieldInfo::new(#name, #generic_token)
}
@@ -104,7 +105,7 @@ pub fn gen_type_def(fields: &[&Field]) -> TokenStream {
}
StructField::HashMapRc(key_ty, _) | StructField::HashMapArc(key_ty, _) => {
let key_generic_tree = parse_generic_tree(key_ty.as_ref());
- let key_generic_token = generic_tree_to_tokens(&key_generic_tree, false);
+ let key_generic_token = generic_tree_to_tokens(&key_generic_tree);
quote! {
fory_core::meta::FieldInfo::new(#name, fory_core::meta::FieldType {
type_id: fory_core::types::TypeId::MAP as u32,
@@ -130,6 +131,6 @@ pub fn gen_type_def(fields: &[&Field]) -> TokenStream {
});
quote! {
let field_infos: Vec<fory_core::meta::FieldInfo> = vec![#(#field_infos),*];
- fory_core::serializer::struct_::type_def::<Self>(fory, type_id, namespace, type_name, register_by_name, &field_infos)
+ fory_core::serializer::struct_::type_def::<Self>(fory, type_id, namespace, type_name, register_by_name, field_infos)
}
}
diff --git a/rust/fory-derive/src/object/read.rs b/rust/fory-derive/src/object/read.rs
index b41e05de0..c87e1bfda 100644
--- a/rust/fory-derive/src/object/read.rs
+++ b/rust/fory-derive/src/object/read.rs
@@ -100,13 +100,12 @@ fn gen_read_match_arm(field: &Field, private_ident: &Ident) -> TokenStream {
let fory_type_id = context.reader.read_varuint32();
- let harness = context.get_fory()
- .get_type_resolver()
+ let harness = fory.get_type_resolver()
.get_harness(fory_type_id)
.expect("Type not registered for trait object field");
let deserializer_fn = harness.get_read_fn();
- let any_box = deserializer_fn(context, true, false)?;
+ let any_box = deserializer_fn(fory, context, true, false)?;
let base_type_id = fory_type_id >> 8;
#private_ident = #helper_mod::#from_any_fn(any_box, base_type_id)?;
@@ -119,7 +118,7 @@ fn gen_read_match_arm(field: &Field, private_ident: &Ident) -> TokenStream {
let trait_ident = types.trait_ident;
quote! {
#name_str => {
- let wrapper = <#wrapper_ty as fory_core::serializer::Serializer>::fory_read(context, true)?;
+ let wrapper = <#wrapper_ty as fory_core::serializer::Serializer>::fory_read(fory, context, true)?;
#private_ident = std::rc::Rc::<dyn #trait_ident>::from(wrapper);
}
}
@@ -130,7 +129,7 @@ fn gen_read_match_arm(field: &Field, private_ident: &Ident) -> TokenStream {
let trait_ident = types.trait_ident;
quote! {
#name_str => {
- let wrapper = <#wrapper_ty as fory_core::serializer::Serializer>::fory_read(context, true)?;
+ let wrapper = <#wrapper_ty as fory_core::serializer::Serializer>::fory_read(fory, context, true)?;
#private_ident = std::sync::Arc::<dyn #trait_ident>::from(wrapper);
}
}
@@ -141,7 +140,7 @@ fn gen_read_match_arm(field: &Field, private_ident: &Ident) -> TokenStream {
let trait_ident = types.trait_ident;
quote! {
#name_str => {
- let wrapper_vec = <Vec<#wrapper_ty> as fory_core::serializer::Serializer>::fory_read(context, true)?;
+ let wrapper_vec = <Vec<#wrapper_ty> as fory_core::serializer::Serializer>::fory_read(fory, context, true)?;
#private_ident = Some(wrapper_vec.into_iter()
.map(|w| std::rc::Rc::<dyn #trait_ident>::from(w))
.collect());
@@ -154,7 +153,7 @@ fn gen_read_match_arm(field: &Field, private_ident: &Ident) -> TokenStream {
let trait_ident = types.trait_ident;
quote! {
#name_str => {
- let wrapper_vec = <Vec<#wrapper_ty> as fory_core::serializer::Serializer>::fory_read(context, true)?;
+ let wrapper_vec = <Vec<#wrapper_ty> as fory_core::serializer::Serializer>::fory_read(fory, context, true)?;
#private_ident = Some(wrapper_vec.into_iter()
.map(|w| std::sync::Arc::<dyn #trait_ident>::from(w))
.collect());
@@ -167,7 +166,7 @@ fn gen_read_match_arm(field: &Field, private_ident: &Ident) -> TokenStream {
let trait_ident = types.trait_ident;
quote! {
#name_str => {
- let wrapper_map = <std::collections::HashMap<#key_ty, #wrapper_ty> as fory_core::serializer::Serializer>::fory_read(context, true)?;
+ let wrapper_map = <std::collections::HashMap<#key_ty, #wrapper_ty> as fory_core::serializer::Serializer>::fory_read(fory, context, true)?;
#private_ident = Some(wrapper_map.into_iter()
.map(|(k, v)| (k, std::rc::Rc::<dyn #trait_ident>::from(v)))
.collect());
@@ -180,7 +179,7 @@ fn gen_read_match_arm(field: &Field, private_ident: &Ident) -> TokenStream {
let trait_ident = types.trait_ident;
quote! {
#name_str => {
- let wrapper_map = <std::collections::HashMap<#key_ty, #wrapper_ty> as fory_core::serializer::Serializer>::fory_read(context, true)?;
+ let wrapper_map = <std::collections::HashMap<#key_ty, #wrapper_ty> as fory_core::serializer::Serializer>::fory_read(fory, context, true)?;
#private_ident = Some(wrapper_map.into_iter()
.map(|(k, v)| (k, std::sync::Arc::<dyn #trait_ident>::from(v)))
.collect());
@@ -190,15 +189,15 @@ fn gen_read_match_arm(field: &Field, private_ident: &Ident) -> TokenStream {
StructField::Forward => {
quote! {
#name_str => {
- #private_ident = Some(fory_core::serializer::Serializer::fory_read(context, true)?);
+ #private_ident = Some(fory_core::serializer::Serializer::fory_read(fory, context, true)?);
}
}
}
_ => {
quote! {
#name_str => {
- let skip_ref_flag = fory_core::serializer::get_skip_ref_flag::<#ty>(context.get_fory());
- #private_ident = Some(fory_core::serializer::read_ref_info_data::<#ty>(context, true, skip_ref_flag, false)?);
+ let skip_ref_flag = fory_core::serializer::get_skip_ref_flag::<#ty>(fory);
+ #private_ident = Some(fory_core::serializer::read_ref_info_data::<#ty>(fory, context, true, skip_ref_flag, false)?);
}
}
}
@@ -207,7 +206,7 @@ fn gen_read_match_arm(field: &Field, private_ident: &Ident) -> TokenStream {
pub fn gen_read_type_info() -> TokenStream {
quote! {
- fory_core::serializer::struct_::read_type_info::<Self>(context, is_field)
+ fory_core::serializer::struct_::read_type_info::<Self>(fory, context, is_field)
}
}
@@ -275,7 +274,8 @@ pub fn gen_read_data(fields: &[&Field]) -> TokenStream {
let loop_ts = get_fields_loop_ts(fields);
quote! {
#(#declare_var_ts)*
- let field_names = <Self as fory_core::serializer::StructSerializer>::fory_get_sorted_field_names(context.get_fory());
+ let field_names = <Self as fory_core::serializer::StructSerializer>::fory_get_sorted_field_names(fory);
+ let field_names = field_names.as_ref();
#loop_ts
}
};
@@ -324,12 +324,11 @@ fn gen_read_compatible_match_arm(field: &Field, var_name: &Ident) -> TokenStream
panic!("Expected NotNullValue for trait object field");
}
let fory_type_id = context.reader.read_varuint32();
- let harness = context.get_fory()
- .get_type_resolver()
+ let harness = fory.get_type_resolver()
.get_harness(fory_type_id)
.expect("Type not registered for trait object field");
let deserializer_fn = harness.get_read_fn();
- let any_box = deserializer_fn(context, true, false).unwrap();
+ let any_box = deserializer_fn(fory, context, true, false).unwrap();
let base_type_id = fory_type_id >> 8;
#var_name = #helper_mod::#from_any_fn(any_box, base_type_id).unwrap();
}
@@ -341,7 +340,7 @@ fn gen_read_compatible_match_arm(field: &Field, var_name: &Ident) -> TokenStream
let trait_ident = types.trait_ident;
quote! {
if _field.field_name.as_str() == #field_name_str {
- let wrapper = <#wrapper_ty as fory_core::serializer::Serializer>::fory_read(context, true).unwrap();
+ let wrapper = <#wrapper_ty as fory_core::serializer::Serializer>::fory_read(fory, context, true).unwrap();
#var_name = Some(std::rc::Rc::<dyn #trait_ident>::from(wrapper));
}
}
@@ -352,7 +351,7 @@ fn gen_read_compatible_match_arm(field: &Field, var_name: &Ident) -> TokenStream
let trait_ident = types.trait_ident;
quote! {
if _field.field_name.as_str() == #field_name_str {
- let wrapper = <#wrapper_ty as fory_core::serializer::Serializer>::fory_read(context, true).unwrap();
+ let wrapper = <#wrapper_ty as fory_core::serializer::Serializer>::fory_read(fory, context, true).unwrap();
#var_name = Some(std::sync::Arc::<dyn #trait_ident>::from(wrapper));
}
}
@@ -363,7 +362,7 @@ fn gen_read_compatible_match_arm(field: &Field, var_name: &Ident) -> TokenStream
let trait_ident = types.trait_ident;
quote! {
if _field.field_name.as_str() == #field_name_str {
- let wrapper_vec = <Vec<#wrapper_ty> as fory_core::serializer::Serializer>::fory_read(context, true).unwrap();
+ let wrapper_vec = <Vec<#wrapper_ty> as fory_core::serializer::Serializer>::fory_read(fory, context, true).unwrap();
#var_name = Some(wrapper_vec.into_iter()
.map(|w| std::rc::Rc::<dyn #trait_ident>::from(w))
.collect());
@@ -376,7 +375,7 @@ fn gen_read_compatible_match_arm(field: &Field, var_name: &Ident) -> TokenStream
let trait_ident = types.trait_ident;
quote! {
if _field.field_name.as_str() == #field_name_str {
- let wrapper_vec = <Vec<#wrapper_ty> as fory_core::serializer::Serializer>::fory_read(context, true).unwrap();
+ let wrapper_vec = <Vec<#wrapper_ty> as fory_core::serializer::Serializer>::fory_read(fory, context, true).unwrap();
#var_name = Some(wrapper_vec.into_iter()
.map(|w| std::sync::Arc::<dyn #trait_ident>::from(w))
.collect());
@@ -389,7 +388,7 @@ fn gen_read_compatible_match_arm(field: &Field, var_name: &Ident) -> TokenStream
let trait_ident = types.trait_ident;
quote! {
if _field.field_name.as_str() == #field_name_str {
- let wrapper_map = <std::collections::HashMap<#key_ty, #wrapper_ty> as fory_core::serializer::Serializer>::fory_read(context, true).unwrap();
+ let wrapper_map = <std::collections::HashMap<#key_ty, #wrapper_ty> as fory_core::serializer::Serializer>::fory_read(fory, context, true).unwrap();
#var_name = Some(wrapper_map.into_iter()
.map(|(k, v)| (k, std::rc::Rc::<dyn #trait_ident>::from(v)))
.collect());
@@ -402,7 +401,7 @@ fn gen_read_compatible_match_arm(field: &Field, var_name: &Ident) -> TokenStream
let trait_ident = types.trait_ident;
quote! {
if _field.field_name.as_str() == #field_name_str {
- let wrapper_map = <std::collections::HashMap<#key_ty, #wrapper_ty> as fory_core::serializer::Serializer>::fory_read(context, true).unwrap();
+ let wrapper_map = <std::collections::HashMap<#key_ty, #wrapper_ty> as fory_core::serializer::Serializer>::fory_read(fory, context, true).unwrap();
#var_name = Some(wrapper_map.into_iter()
.map(|(k, v)| (k, std::sync::Arc::<dyn #trait_ident>::from(v)))
.collect());
@@ -412,21 +411,21 @@ fn gen_read_compatible_match_arm(field: &Field, var_name: &Ident) -> TokenStream
StructField::ContainsTraitObject => {
quote! {
if _field.field_name.as_str() == #field_name_str {
- let skip_ref_flag = fory_core::serializer::get_skip_ref_flag::<#ty>(context.get_fory());
- #var_name = Some(fory_core::serializer::read_ref_info_data::<#ty>(context, true, skip_ref_flag, false)?);
+ let skip_ref_flag = fory_core::serializer::get_skip_ref_flag::<#ty>(fory);
+ #var_name = Some(fory_core::serializer::read_ref_info_data::<#ty>(fory, context, true, skip_ref_flag, false)?);
}
}
}
StructField::Forward => {
quote! {
if _field.field_name.as_str() == #field_name_str {
- #var_name = Some(fory_core::serializer::Serializer::fory_read(context, true).unwrap());
+ #var_name = Some(fory_core::serializer::Serializer::fory_read(fory, context, true).unwrap());
}
}
}
StructField::None => {
let generic_tree = parse_generic_tree(ty);
- let generic_token = generic_tree_to_tokens(&generic_tree, true);
+ let generic_token = generic_tree_to_tokens(&generic_tree);
let read_nullable_fn_name = create_read_nullable_fn_name(field);
let _base_ty = match &ty {
@@ -437,22 +436,23 @@ fn gen_read_compatible_match_arm(field: &Field, var_name: &Ident) -> TokenStream
if _field.field_name.as_str() == #field_name_str {
let local_field_type = #generic_token;
if &_field.field_type == &local_field_type {
- let skip_ref_flag = fory_core::serializer::get_skip_ref_flag::<#ty>(context.get_fory());
- #var_name = Some(fory_core::serializer::read_ref_info_data::<#ty>(context, true, skip_ref_flag, false).unwrap_or_else(|_err| {
+ let skip_ref_flag = fory_core::serializer::get_skip_ref_flag::<#ty>(fory);
+ #var_name = Some(fory_core::serializer::read_ref_info_data::<#ty>(fory, context, true, skip_ref_flag, false).unwrap_or_else(|_err| {
panic!("Err at deserializing {:?}: {:?}", #field_name_str, _err);
}));
} else {
- let local_nullable_type = fory_core::meta::NullableFieldType::from(local_field_type.clone());
- let remote_nullable_type = fory_core::meta::NullableFieldType::from(_field.field_type.clone());
+ let local_nullable_type = fory_core::meta::NullableFieldType::from(&local_field_type);
+ let remote_nullable_type = fory_core::meta::NullableFieldType::from(&_field.field_type);
if local_nullable_type != remote_nullable_type {
println!("Type not match, just skip: {}", #field_name_str);
let read_ref_flag = fory_core::serializer::skip::get_read_ref_flag(&remote_nullable_type);
- fory_core::serializer::skip::skip_field_value(context, &remote_nullable_type, read_ref_flag).unwrap();
+ fory_core::serializer::skip::skip_field_value(fory, context, &remote_nullable_type, read_ref_flag).unwrap();
#var_name = Some(<#ty as fory_core::serializer::ForyDefault>::fory_default());
} else {
println!("Try to deserialize_compatible: {}", #field_name_str);
#var_name = Some(
Self::#read_nullable_fn_name(
+ fory,
context,
&local_nullable_type,
&remote_nullable_type
@@ -472,13 +472,13 @@ pub fn gen_read(struct_ident: &Ident) -> TokenStream {
quote! {
let ref_flag = context.reader.read_i8();
if ref_flag == (fory_core::types::RefFlag::NotNullValue as i8) || ref_flag == (fory_core::types::RefFlag::RefValue as i8) {
- match context.get_fory().get_mode() {
+ match fory.get_mode() {
fory_core::types::Mode::SchemaConsistent => {
- <Self as fory_core::serializer::Serializer>::fory_read_type_info(context, false);
- <Self as fory_core::serializer::Serializer>::fory_read_data(context, false)
+ <Self as fory_core::serializer::Serializer>::fory_read_type_info(fory, context, false);
+ <Self as fory_core::serializer::Serializer>::fory_read_data(fory, context, false)
},
fory_core::types::Mode::Compatible => {
- <#struct_ident as fory_core::serializer::Serializer>::fory_read_compatible(context)
+ <#struct_ident as fory_core::serializer::Serializer>::fory_read_compatible(fory, context)
},
_ => unreachable!()
}
@@ -512,20 +512,21 @@ pub fn gen_read_compatible(fields: &[&Field]) -> TokenStream {
};
#(#declare_ts)*
- let local_type_def = context.get_fory().get_type_resolver().get_type_info(std::any::TypeId::of::<Self>()).get_type_def();
+ let local_type_def = fory.get_type_resolver().get_type_info(std::any::TypeId::of::<Self>()).get_type_def();
let high_bytes = &local_type_def[..8];
let local_type_hash = i64::from_le_bytes(high_bytes.try_into().unwrap());
if meta.get_hash() == local_type_hash {
// fast path
- let field_names = <Self as fory_core::serializer::StructSerializer>::fory_get_sorted_field_names(context.get_fory());
+ let field_names = <Self as fory_core::serializer::StructSerializer>::fory_get_sorted_field_names(fory);
+ let field_names = field_names.as_ref();
#consistent_fields_loop_ts
} else {
for _field in fields.iter() {
#(#pattern_items else)* {
println!("skip {:?}:{:?}", _field.field_name.as_str(), _field.field_type);
- let nullable_field_type = fory_core::meta::NullableFieldType::from(_field.field_type.clone());
+ let nullable_field_type = fory_core::meta::NullableFieldType::from(&_field.field_type);
let read_ref_flag = fory_core::serializer::skip::get_read_ref_flag(&nullable_field_type);
- fory_core::serializer::skip::skip_field_value(context, &nullable_field_type, read_ref_flag).unwrap();
+ fory_core::serializer::skip::skip_field_value(fory, context, &nullable_field_type, read_ref_flag).unwrap();
}
}
}
@@ -548,6 +549,7 @@ pub fn gen_read_nullable(fields: &[&Field]) -> TokenStream {
let read_tokens = nullable_generic_tree.to_read_tokens(&vec![], true);
Some(quote! {
fn #fn_name(
+ fory: &fory_core::fory::Fory,
context: &mut fory_core::resolver::context::ReadContext,
local_nullable_type: &fory_core::meta::NullableFieldType,
remote_nullable_type: &fory_core::meta::NullableFieldType
diff --git a/rust/fory-derive/src/object/serializer.rs b/rust/fory-derive/src/object/serializer.rs
index fc76ba9be..20f0421c4 100644
--- a/rust/fory-derive/src/object/serializer.rs
+++ b/rust/fory-derive/src/object/serializer.rs
@@ -135,7 +135,7 @@ pub fn derive_serializer(ast: &syn::DeriveInput) -> TokenStream {
#actual_type_id_ts
}
- fn fory_get_sorted_field_names(fory: &fory_core::fory::Fory) -> Vec<String> {
+ fn fory_get_sorted_field_names(fory: &fory_core::fory::Fory) -> std::sync::Arc<Vec<String>> {
#get_sorted_field_names_ts
}
@@ -160,31 +160,31 @@ pub fn derive_serializer(ast: &syn::DeriveInput) -> TokenStream {
#reserved_space_ts
}
- fn fory_write_type_info(context: &mut fory_core::resolver::context::WriteContext, is_field: bool) {
+ fn fory_write_type_info(fory: &fory_core::fory::Fory, context: &mut fory_core::resolver::context::WriteContext, is_field: bool) {
#write_type_info_ts
}
- fn fory_read_type_info(context: &mut fory_core::resolver::context::ReadContext, is_field: bool) {
+ fn fory_read_type_info(fory: &fory_core::fory::Fory, context: &mut fory_core::resolver::context::ReadContext, is_field: bool) {
#read_type_info_ts
}
- fn fory_write_data(&self, context: &mut fory_core::resolver::context::WriteContext, is_field: bool) {
+ fn fory_write_data(&self, fory: &fory_core::fory::Fory, context: &mut fory_core::resolver::context::WriteContext, is_field: bool) {
#write_data_ts
}
- fn fory_read_data(context: &mut fory_core::resolver::context::ReadContext, is_field: bool) -> Result<Self, fory_core::error::Error> {
+ fn fory_read_data(fory: &fory_core::fory::Fory, context: &mut fory_core::resolver::context::ReadContext, is_field: bool) -> Result<Self, fory_core::error::Error> {
#read_data_ts
}
- fn fory_write(&self, context: &mut fory_core::resolver::context::WriteContext, is_field: bool) {
+ fn fory_write(&self, fory: &fory_core::fory::Fory, context: &mut fory_core::resolver::context::WriteContext, is_field: bool) {
#write_ts
}
- fn fory_read(context: &mut fory_core::resolver::context::ReadContext, is_field: bool) -> Result<Self, fory_core::error::Error> {
+ fn fory_read(fory: &fory_core::fory::Fory, context: &mut fory_core::resolver::context::ReadContext, is_field: bool) -> Result<Self, fory_core::error::Error> {
#read_ts
}
- fn fory_read_compatible(context: &mut fory_core::resolver::context::ReadContext) -> Result<Self, fory_core::error::Error> {
+ fn fory_read_compatible(fory: &fory_core::fory::Fory, context: &mut fory_core::resolver::context::ReadContext) -> Result<Self, fory_core::error::Error> {
#read_compatible_ts
}
}
diff --git a/rust/fory-derive/src/object/util.rs b/rust/fory-derive/src/object/util.rs
index 6eee2120e..8626bf462 100644
--- a/rust/fory-derive/src/object/util.rs
+++ b/rust/fory-derive/src/object/util.rs
@@ -230,15 +230,15 @@ macro_rules! basic_type_deserialize {
$ty_str => {
if $nullable {
quote! {
- <$ty as fory_core::serializer::Serializer>::fory_read_type_info(context, true);
- let res1 = Some(<$ty as fory_core::serializer::Serializer>::fory_read_data(context, true)
+ <$ty as fory_core::serializer::Serializer>::fory_read_type_info(fory, context, true);
+ let res1 = Some(<$ty as fory_core::serializer::Serializer>::fory_read_data(fory, context, true)
.map_err(fory_core::error::Error::from)?);
Ok::<Option<$ty>, fory_core::error::Error>(res1)
}
} else {
quote! {
- <$ty as fory_core::serializer::Serializer>::fory_read_type_info(context, true);
- let res2 = <$ty as fory_core::serializer::Serializer>::fory_read_data(context, true)
+ <$ty as fory_core::serializer::Serializer>::fory_read_type_info(fory, context, true);
+ let res2 = <$ty as fory_core::serializer::Serializer>::fory_read_data(fory, context, true)
.map_err(fory_core::error::Error::from)?;
Ok::<$ty, fory_core::error::Error>(res2)
}
@@ -310,8 +310,8 @@ impl NullableTypeNode {
let res1 = if cur_remote_nullable_type.nullable && ref_flag == (fory_core::types::RefFlag::Null as i8) {
None
} else {
- <#ty_type as fory_core::serializer::Serializer>::fory_read_type_info(context, true);
- Some(<#ty_type as fory_core::serializer::Serializer>::fory_read_data(context, true)
+ <#ty_type as fory_core::serializer::Serializer>::fory_read_type_info(fory, context, true);
+ Some(<#ty_type as fory_core::serializer::Serializer>::fory_read_data(fory, context, true)
.map_err(fory_core::error::Error::from)?)
};
Ok::<Option<#ty_type>, fory_core::error::Error>(res1)
@@ -321,8 +321,8 @@ impl NullableTypeNode {
let res2 = if cur_remote_nullable_type.nullable && ref_flag == (fory_core::types::RefFlag::Null as i8) {
Vec::default()
} else {
- <#ty_type as fory_core::serializer::Serializer>::fory_read_type_info(context, true);
- <#ty_type as fory_core::serializer::Serializer>::fory_read_data(context, true)
+ <#ty_type as fory_core::serializer::Serializer>::fory_read_type_info(fory, context, true);
+ <#ty_type as fory_core::serializer::Serializer>::fory_read_data(fory, context, true)
.map_err(fory_core::error::Error::from)?
};
Ok::<#ty_type, fory_core::error::Error>(res2)
@@ -490,8 +490,8 @@ impl NullableTypeNode {
continue;
}
let chunk_size = context.reader.read_u8();
- <#key_ty as fory_core::serializer::Serializer>::fory_read_type_info(context, true);
- <#val_ty as fory_core::serializer::Serializer>::fory_read_type_info(context, true);
+ <#key_ty as fory_core::serializer::Serializer>::fory_read_type_info(fory, context, true);
+ <#val_ty as fory_core::serializer::Serializer>::fory_read_type_info(fory, context, true);
for _ in (0..chunk_size).enumerate() {
let key: #key_ty = {#key_tokens}?;
let value: #val_ty = {#val_tokens}?;
@@ -543,7 +543,7 @@ impl NullableTypeNode {
|| internal_id == EXT_ID
|| internal_id == NAMED_EXT_ID
{
- <#nullable_ty as fory_core::serializer::Serializer>::fory_read_compatible(context)
+ <#nullable_ty as fory_core::serializer::Serializer>::fory_read_compatible(fory, context)
.map_err(fory_core::error::Error::from)?
} else {
unimplemented!()
@@ -566,7 +566,7 @@ impl NullableTypeNode {
|| internal_id == EXT_ID
|| internal_id == NAMED_EXT_ID
{
- <#nullable_ty as fory_core::serializer::Serializer>::fory_read_compatible(context)
+ <#nullable_ty as fory_core::serializer::Serializer>::fory_read_compatible(fory, context)
.map_err(fory_core::error::Error::from)?
} else {
unimplemented!()
@@ -741,7 +741,7 @@ pub(super) fn parse_generic_tree(ty: &Type) -> TypeNode {
TypeNode { name, generics }
}
-pub(super) fn generic_tree_to_tokens(node: &TypeNode, have_context: bool) -> TokenStream {
+pub(super) fn generic_tree_to_tokens(node: &TypeNode) -> TokenStream {
if node.name == "Option" {
if let Some(first_generic) = node.generics.first() {
if first_generic.name == "Option" {
@@ -758,23 +758,11 @@ pub(super) fn generic_tree_to_tokens(node: &TypeNode, have_context: bool) -> Tok
let primitive_vec = try_primitive_vec_type(node);
let children_tokens: Vec<TokenStream> = if primitive_vec.is_none() {
- node.generics
- .iter()
- .map(|child| generic_tree_to_tokens(child, have_context))
- .collect()
+ node.generics.iter().map(generic_tree_to_tokens).collect()
} else {
vec![]
};
let ty: syn::Type = syn::parse_str(&node.to_string()).unwrap();
- let param = if have_context {
- quote! {
- context.get_fory()
- }
- } else {
- quote! {
- fory
- }
- };
let get_type_id = if node.name == "Option" {
let option_type_id = TypeId::ForyNullable as u32;
quote! { #option_type_id }
@@ -782,7 +770,7 @@ pub(super) fn generic_tree_to_tokens(node: &TypeNode, have_context: bool) -> Tok
ts
} else {
quote! {
- <#ty as fory_core::serializer::Serializer>::fory_get_type_id(#param)
+ <#ty as fory_core::serializer::Serializer>::fory_get_type_id(fory)
}
};
quote! {
@@ -1055,8 +1043,7 @@ pub(super) fn get_sort_fields_ts(fields: &[&Field]) -> TokenStream {
},
quote! {
final_fields.sort_by(#sorter_ts);
- let final_field_names: Vec<String> = final_fields.iter().map(|(_, name)| name.clone()).collect();
- sorted_field_names.extend(final_field_names);
+ for (_, name) in final_fields.drain(..) { sorted_field_names.push(name); }
},
)
}
@@ -1071,8 +1058,7 @@ pub(super) fn get_sort_fields_ts(fields: &[&Field]) -> TokenStream {
},
quote! {
other_fields.sort_by(#sorter_ts);
- let other_field_names: Vec<String> = other_fields.iter().map(|(_, name)| name.clone()).collect();
- sorted_field_names.extend(other_field_names);
+ for (_, name) in other_fields.drain(..) { sorted_field_names.push(name); }
},
)
}
@@ -1138,6 +1124,8 @@ pub(super) fn get_sort_fields_ts(fields: &[&Field]) -> TokenStream {
let (final_declare, final_extend) = final_fields_declare_extend_ts;
let (other_declare, other_extend) = other_fields_declare_extend_ts;
+ let fields_len = fields.len();
+
quote! {
let sorted_field_names = {
#all_primitive_declare
@@ -1148,7 +1136,7 @@ pub(super) fn get_sort_fields_ts(fields: &[&Field]) -> TokenStream {
#trait_object_fields_ts
#group_sort_enum_other_fields
- let mut sorted_field_names: Vec<String> = Vec::new();
+ let mut sorted_field_names: Vec<String> = Vec::with_capacity(#fields_len);
#all_primitive_extend
#final_extend
#other_extend
diff --git a/rust/fory-derive/src/object/write.rs b/rust/fory-derive/src/object/write.rs
index 5aa862084..6adba6780 100644
--- a/rust/fory-derive/src/object/write.rs
+++ b/rust/fory-derive/src/object/write.rs
@@ -94,7 +94,7 @@ pub fn gen_reserved_space(fields: &[&Field]) -> TokenStream {
pub fn gen_write_type_info() -> TokenStream {
quote! {
- fory_core::serializer::struct_::write_type_info::<Self>(context, is_field)
+ fory_core::serializer::struct_::write_type_info::<Self>(fory, context, is_field)
}
}
@@ -109,21 +109,20 @@ fn gen_write_match_arm(field: &Field) -> TokenStream {
#name_str => {
let any_ref = self.#ident.as_any();
let concrete_type_id = any_ref.type_id();
- let fory_type_id = context.get_fory()
- .get_type_resolver()
+ let fory_type_id = fory.get_type_resolver()
.get_fory_type_id(concrete_type_id)
.expect("Type not registered for trait object field");
context.writer.write_i8(fory_core::types::RefFlag::NotNullValue as i8);
context.writer.write_varuint32(fory_type_id);
- let harness = context.get_fory()
+ let harness = fory
.get_type_resolver()
.get_harness(fory_type_id)
.expect("Harness not found for trait object field");
let serializer_fn = harness.get_write_fn();
- serializer_fn(any_ref, context, true);
+ serializer_fn(any_ref, fory, context, true);
}
}
}
@@ -134,7 +133,7 @@ fn gen_write_match_arm(field: &Field) -> TokenStream {
quote! {
#name_str => {
let wrapper = #wrapper_ty::from(self.#ident.clone() as std::rc::Rc<dyn #trait_ident>);
- fory_core::serializer::Serializer::fory_write(&wrapper, context, true);
+ fory_core::serializer::Serializer::fory_write(&wrapper, fory, context, true);
}
}
}
@@ -145,7 +144,7 @@ fn gen_write_match_arm(field: &Field) -> TokenStream {
quote! {
#name_str => {
let wrapper = #wrapper_ty::from(self.#ident.clone() as std::sync::Arc<dyn #trait_ident>);
- fory_core::serializer::Serializer::fory_write(&wrapper, context, true);
+ fory_core::serializer::Serializer::fory_write(&wrapper, fory, context, true);
}
}
}
@@ -158,7 +157,7 @@ fn gen_write_match_arm(field: &Field) -> TokenStream {
let wrapper_vec: Vec<#wrapper_ty> = self.#ident.iter()
.map(|item| #wrapper_ty::from(item.clone() as std::rc::Rc<dyn #trait_ident>))
.collect();
- fory_core::serializer::Serializer::fory_write(&wrapper_vec, context, true);
+ fory_core::serializer::Serializer::fory_write(&wrapper_vec, fory, context, true);
}
}
}
@@ -171,7 +170,7 @@ fn gen_write_match_arm(field: &Field) -> TokenStream {
let wrapper_vec: Vec<#wrapper_ty> = self.#ident.iter()
.map(|item| #wrapper_ty::from(item.clone() as std::sync::Arc<dyn #trait_ident>))
.collect();
- fory_core::serializer::Serializer::fory_write(&wrapper_vec, context, true);
+ fory_core::serializer::Serializer::fory_write(&wrapper_vec, fory, context, true);
}
}
}
@@ -184,7 +183,7 @@ fn gen_write_match_arm(field: &Field) -> TokenStream {
let wrapper_map: std::collections::HashMap<#key_ty, #wrapper_ty> = self.#ident.iter()
.map(|(k, v)| (k.clone(), #wrapper_ty::from(v.clone() as std::rc::Rc<dyn #trait_ident>)))
.collect();
- fory_core::serializer::Serializer::fory_write(&wrapper_map, context, true);
+ fory_core::serializer::Serializer::fory_write(&wrapper_map, fory, context, true);
}
}
}
@@ -197,22 +196,22 @@ fn gen_write_match_arm(field: &Field) -> TokenStream {
let wrapper_map: std::collections::HashMap<#key_ty, #wrapper_ty> = self.#ident.iter()
.map(|(k, v)| (k.clone(), #wrapper_ty::from(v.clone() as std::sync::Arc<dyn #trait_ident>)))
.collect();
- fory_core::serializer::Serializer::fory_write(&wrapper_map, context, true);
+ fory_core::serializer::Serializer::fory_write(&wrapper_map, fory, context, true);
}
}
}
StructField::Forward => {
quote! {
#name_str => {
- fory_core::serializer::Serializer::fory_write(&self.#ident, context, true);
+ fory_core::serializer::Serializer::fory_write(&self.#ident, fory, context, true);
}
}
}
_ => {
quote! {
#name_str => {
- let skip_ref_flag = fory_core::serializer::get_skip_ref_flag::<#ty>(context.get_fory());
- fory_core::serializer::write_ref_info_data::<#ty>(&self.#ident, context, true, skip_ref_flag, false);
+ let skip_ref_flag = fory_core::serializer::get_skip_ref_flag::<#ty>(fory);
+ fory_core::serializer::write_ref_info_data::<#ty>(&self.#ident, fory, context, true, skip_ref_flag, false);
}
}
}
@@ -253,7 +252,8 @@ pub fn gen_write_data(fields: &[&Field]) -> TokenStream {
}
};
quote! {
- let sorted_field_names = <Self as fory_core::serializer::StructSerializer>::fory_get_sorted_field_names(context.get_fory());
+ let sorted_field_names = <Self as fory_core::serializer::StructSerializer>::fory_get_sorted_field_names(fory);
+ let sorted_field_names = sorted_field_names.as_ref();
#loop_ts
}
};
@@ -264,6 +264,6 @@ pub fn gen_write_data(fields: &[&Field]) -> TokenStream {
pub fn gen_write() -> TokenStream {
quote! {
- fory_core::serializer::struct_::write::<Self>(self, context, is_field)
+ fory_core::serializer::struct_::write::<Self>(self, fory, context, is_field)
}
}
diff --git a/rust/fory/src/lib.rs b/rust/fory/src/lib.rs
index faaae0d26..c5d90d628 100644
--- a/rust/fory/src/lib.rs
+++ b/rust/fory/src/lib.rs
@@ -717,13 +717,13 @@
//! }
//!
//! impl Serializer for CustomType {
-//! fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
+//! fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
//! context.writer.write_i32(self.value);
//! context.writer.write_varuint32(self.name.len() as u32);
//! context.writer.write_utf8_string(&self.name);
//! }
//!
-//! fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
+//! fn fory_read_data(fory: &Fory, context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
//! let value = context.reader.read_i32();
//! let len = context.reader.read_varuint32() as usize;
//! let name = context.reader.read_utf8_string(len);
diff --git a/rust/tests/tests/compatible/test_basic_type.rs b/rust/tests/tests/compatible/test_basic_type.rs
index 7756dad9b..7efdac654 100644
--- a/rust/tests/tests/compatible/test_basic_type.rs
+++ b/rust/tests/tests/compatible/test_basic_type.rs
@@ -439,13 +439,13 @@ fn deserialize_nullable(fory: &Fory, context: &mut ReadContext, auto_conv: bool,
fn basic() {
let fory = Fory::default().mode(Compatible);
// serialize
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
serialize_non_null(&fory, &mut write_context);
// deserialize
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
deserialize_non_null(&fory, &mut read_context, false, true);
}
@@ -454,13 +454,13 @@ fn basic() {
fn basic_nullable() {
let fory = Fory::default().mode(Compatible);
// serialize
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
serialize_nullable(&fory, &mut write_context);
// deserialize
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
deserialize_nullable(&fory, &mut read_context, false, true);
}
@@ -469,21 +469,21 @@ fn basic_nullable() {
fn auto_conv() {
let fory = Fory::default().mode(Compatible);
// serialize_non-null
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
serialize_non_null(&fory, &mut write_context);
// deserialize_nullable
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context: ReadContext<'_, '_> = ReadContext::new(&fory, reader, 5);
+ let mut read_context: ReadContext = ReadContext::new(reader, 5);
deserialize_nullable(&fory, &mut read_context, true, true);
// serialize_nullable
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
serialize_nullable(&fory, &mut write_context);
// deserialize_non-null
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
deserialize_non_null(&fory, &mut read_context, true, true);
}
diff --git a/rust/tests/tests/compatible/test_container.rs b/rust/tests/tests/compatible/test_container.rs
index 78ad8e443..e6e6426cb 100644
--- a/rust/tests/tests/compatible/test_container.rs
+++ b/rust/tests/tests/compatible/test_container.rs
@@ -223,15 +223,15 @@ fn complex_container2() -> Vec<HashMap<Vec<Item>, Vec<Item>>> {
fn container_outer_auto_conv() {
let fory = Fory::default().mode(Compatible);
// serialize_outer_non-null
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
fory.serialize_with_context(&basic_list(), &mut write_context);
fory.serialize_with_context(&basic_set(), &mut write_context);
fory.serialize_with_context(&basic_map(), &mut write_context);
// deserialize_outer_nullable
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
assert_eq!(
Some(basic_list()),
fory.deserialize_with_context::<Option<Vec<String>>>(&mut read_context)
@@ -249,8 +249,8 @@ fn container_outer_auto_conv() {
);
assert_eq!(read_context.reader.slice_after_cursor().len(), 0);
// serialize_outer_nullable
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
fory.serialize_with_context(&Some(basic_list()), &mut write_context);
fory.serialize_with_context(&Some(basic_set()), &mut write_context);
fory.serialize_with_context(&Some(basic_map()), &mut write_context);
@@ -260,7 +260,7 @@ fn container_outer_auto_conv() {
// deserialize_outer_non-null
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
assert_eq!(
basic_list(),
fory.deserialize_with_context::<Vec<String>>(&mut read_context)
@@ -302,8 +302,8 @@ fn collection_inner() {
fory2.register_by_name::<Item>("item");
for fory in [fory1, fory2] {
// serialize
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
fory.serialize_with_context(&basic_list(), &mut write_context);
fory.serialize_with_context(&item_list(), &mut write_context);
fory.serialize_with_context(&basic_set(), &mut write_context);
@@ -315,7 +315,7 @@ fn collection_inner() {
// deserialize
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
assert_eq!(
basic_list(),
fory.deserialize_with_context::<Vec<String>>(&mut read_context)
@@ -368,8 +368,8 @@ fn collection_inner_auto_conv() {
fory2.register_by_name::<Item>("item");
for fory in [fory1, fory2] {
// serialize_non-null
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
fory.serialize_with_context(&basic_list(), &mut write_context);
fory.serialize_with_context(&item_list(), &mut write_context);
fory.serialize_with_context(&basic_set(), &mut write_context);
@@ -377,7 +377,7 @@ fn collection_inner_auto_conv() {
// deserialize_nullable
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
assert_eq!(
nullable_basic_list(true),
fory.deserialize_with_context::<Vec<Option<String>>>(&mut read_context)
@@ -400,8 +400,8 @@ fn collection_inner_auto_conv() {
);
assert_eq!(read_context.reader.slice_after_cursor().len(), 0);
// serialize_nullable
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
fory.serialize_with_context(&nullable_basic_list(false), &mut write_context);
fory.serialize_with_context(&nullable_item_list(false), &mut write_context);
fory.serialize_with_context(&nullable_basic_set(false), &mut write_context);
@@ -409,7 +409,7 @@ fn collection_inner_auto_conv() {
// deserialize_non-null
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
assert_eq!(
basic_list(),
fory.deserialize_with_context::<Vec<String>>(&mut read_context)
@@ -442,8 +442,8 @@ fn map_inner() {
fory2.register_by_name::<Item>("item");
for fory in [fory1, fory2] {
// serialize
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
fory.serialize_with_context(&basic_map(), &mut write_context);
fory.serialize_with_context(&item_map(), &mut write_context);
fory.serialize_with_context(&nullable_basic_map(false), &mut write_context);
@@ -451,7 +451,7 @@ fn map_inner() {
// deserialize
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
assert_eq!(
basic_map(),
fory.deserialize_with_context::<HashMap<String, String>>(&mut read_context)
@@ -486,14 +486,14 @@ fn map_inner_auto_conv() {
fory2.register_by_name::<Item>("item");
for fory in [fory1, fory2] {
// serialize_non-null
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
fory.serialize_with_context(&basic_map(), &mut write_context);
fory.serialize_with_context(&item_map(), &mut write_context);
// deserialize_nullable
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
assert_eq!(
nullable_basic_map(true),
fory.deserialize_with_context::<HashMap<Option<String>, Option<String>>>(
@@ -508,14 +508,14 @@ fn map_inner_auto_conv() {
);
assert_eq!(read_context.reader.slice_after_cursor().len(), 0);
// serialize_nullable
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
fory.serialize_with_context(&nullable_basic_map(false), &mut write_context);
fory.serialize_with_context(&nullable_item_map(false), &mut write_context);
// deserialize_non-null
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
assert_eq!(
basic_map(),
fory.deserialize_with_context::<HashMap<String, String>>(&mut read_context)
@@ -537,14 +537,14 @@ fn complex() {
let mut fory2 = Fory::default().mode(Compatible);
fory2.register_by_name::<Item>("item");
for fory in [fory1, fory2] {
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
fory.serialize_with_context(&nested_collection(), &mut write_context);
fory.serialize_with_context(&complex_container1(), &mut write_context);
fory.serialize_with_context(&complex_container2(), &mut write_context);
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
assert_eq!(
nested_collection(),
fory.deserialize_with_context::<Vec<HashSet<Item>>>(&mut read_context)
diff --git a/rust/tests/tests/compatible/test_struct_enum.rs b/rust/tests/tests/compatible/test_struct_enum.rs
index 6b8791a9f..22778b32e 100644
--- a/rust/tests/tests/compatible/test_struct_enum.rs
+++ b/rust/tests/tests/compatible/test_struct_enum.rs
@@ -91,14 +91,14 @@ fn basic() {
fory2.register_by_name::<Item>("item");
fory2.register_by_name::<Person>("person");
for fory in [fory1, fory2] {
- let mut writer = Writer::default();
- let mut write_context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut write_context = WriteContext::new(writer);
let person = Person::default();
fory.serialize_with_context(&person, &mut write_context);
fory.serialize_with_context(&person, &mut write_context);
let bytes = write_context.writer.dump();
let reader = Reader::new(bytes.as_slice());
- let mut read_context = ReadContext::new(&fory, reader, 5);
+ let mut read_context = ReadContext::new(reader, 5);
assert_eq!(
person,
fory.deserialize_with_context::<Person>(&mut read_context)
@@ -395,12 +395,16 @@ fn ext() {
}
}
impl Serializer for ExtItem {
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- write_data(&self.id, context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_data(&self.id, fory, context, is_field);
}
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
Ok(Self {
- id: read_data(context, is_field)?,
+ id: read_data(fory, context, is_field)?,
})
}
@@ -441,12 +445,16 @@ fn skip_ext() {
id: i32,
}
impl Serializer for ExtItem {
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- write_data(&self.id, context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_data(&self.id, fory, context, is_field);
}
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
Ok(Self {
- id: read_data(context, is_field)?,
+ id: read_data(fory, context, is_field)?,
})
}
@@ -500,12 +508,16 @@ fn compatible_ext() {
id: i32,
}
impl Serializer for ExtItem {
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- write_data(&self.id, context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_data(&self.id, fory, context, is_field);
}
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
Ok(Self {
- id: read_data(context, is_field)?,
+ id: read_data(fory, context, is_field)?,
})
}
fn fory_type_id_dyn(&self, fory: &Fory) -> u32 {
diff --git a/rust/tests/tests/test_cross_language.rs b/rust/tests/tests/test_cross_language.rs
index 1d25e960f..29e95c1df 100644
--- a/rust/tests/tests/test_cross_language.rs
+++ b/rust/tests/tests/test_cross_language.rs
@@ -229,13 +229,13 @@ fn test_string_serializer() {
.mode(Compatible)
.xlang(true)
.compress_string(false);
- let mut context = ReadContext::new(&fory, reader, 5);
+ let mut context = ReadContext::new(reader, 5);
let reader_compress = Reader::new(bytes.as_slice());
let fory_compress = Fory::default()
.mode(Compatible)
.xlang(true)
.compress_string(true);
- let mut context_compress = ReadContext::new(&fory_compress, reader_compress, 5);
+ let mut context_compress = ReadContext::new(reader_compress, 5);
let test_strings: Vec<String> = vec![
// Latin1
"ab".to_string(),
@@ -250,17 +250,20 @@ fn test_string_serializer() {
];
for s in &test_strings {
// make is_field=true to skip read/write type_id
- assert_eq!(*s, String::fory_read_data(&mut context, true).unwrap());
assert_eq!(
*s,
- String::fory_read_data(&mut context_compress, true).unwrap()
+ String::fory_read_data(&fory, &mut context, true).unwrap()
+ );
+ assert_eq!(
+ *s,
+ String::fory_read_data(&fory_compress, &mut context_compress, true).unwrap()
);
}
- let mut writer = Writer::default();
+ let writer = Writer::default();
let fory = Fory::default().mode(Compatible).xlang(true);
- let mut context = WriteContext::new(&fory, &mut writer);
+ let mut context = WriteContext::new(writer);
for s in &test_strings {
- s.fory_write_data(&mut context, true);
+ s.fory_write_data(&fory, &mut context, true);
}
fs::write(&data_file_path, context.writer.dump()).unwrap();
}
@@ -291,7 +294,7 @@ fn test_cross_language_serializer() {
let reader = Reader::new(bytes.as_slice());
let mut fory = Fory::default().mode(Compatible).xlang(true);
fory.register::<Color>(101);
- let mut context = ReadContext::new(&fory, reader, 5);
+ let mut context = ReadContext::new(reader, 5);
assert_de!(fory, context, bool, true);
assert_de!(fory, context, bool, false);
assert_de!(fory, context, i32, -1);
@@ -319,8 +322,8 @@ fn test_cross_language_serializer() {
assert_de!(fory, context, HashMap::<String, String>, str_map);
assert_de!(fory, context, Color, color);
- let mut writer = Writer::default();
- let mut context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut context = WriteContext::new(writer);
fory.serialize_with_context(&true, &mut context);
fory.serialize_with_context(&false, &mut context);
fory.serialize_with_context(&-1, &mut context);
@@ -421,7 +424,7 @@ fn test_list() {
let mut fory = Fory::default().mode(Compatible);
fory.register::<Item>(102);
let reader = Reader::new(bytes.as_slice());
- let mut context = ReadContext::new(&fory, reader, 5);
+ let mut context = ReadContext::new(reader, 5);
let str_list = vec![Some("a".to_string()), Some("b".to_string())];
let str_list2 = vec![None, Some("b".to_string())];
@@ -447,8 +450,8 @@ fn test_list() {
let remote_item_list2: Vec<Option<Item>> = fory.deserialize_with_context(&mut context).unwrap();
assert_eq!(remote_item_list2, item_list2);
- let mut writer = Writer::default();
- let mut context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut context = WriteContext::new(writer);
fory.serialize_with_context(&remote_str_list, &mut context);
fory.serialize_with_context(&remote_str_list2, &mut context);
fory.serialize_with_context(&remote_item_list, &mut context);
@@ -466,7 +469,7 @@ fn test_map() {
let mut fory = Fory::default().mode(Compatible);
fory.register::<Item>(102);
let reader = Reader::new(bytes.as_slice());
- let mut context = ReadContext::new(&fory, reader, 5);
+ let mut context = ReadContext::new(reader, 5);
let str_map = HashMap::from([
(Some("k1".to_string()), Some("v1".to_string())),
@@ -536,7 +539,7 @@ fn test_integer() {
fory.register::<Item2>(101);
let reader = Reader::new(bytes.as_slice());
- let mut context = ReadContext::new(&fory, reader, 5);
+ let mut context = ReadContext::new(reader, 5);
let f1 = 1;
let f2 = Some(2);
let f3 = Some(3);
@@ -567,8 +570,8 @@ fn test_integer() {
let remote_f6: Option<i32> = fory.deserialize_with_context(&mut context).unwrap();
assert_eq!(remote_f6, f6);
- let mut writer = Writer::default();
- let mut context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut context = WriteContext::new(writer);
fory.serialize_with_context(&remote_item2, &mut context);
fory.serialize_with_context(&remote_f1, &mut context);
fory.serialize_with_context(&remote_f2, &mut context);
@@ -588,15 +591,19 @@ struct MyExt {
id: i32,
}
impl Serializer for MyExt {
- fn fory_write_data(&self, context: &mut WriteContext, _is_field: bool) {
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, _is_field: bool) {
// set is_field=false to write type_id like in java
- write_data(&self.id, context, false);
+ write_data(&self.id, fory, context, false);
}
- fn fory_read_data(context: &mut ReadContext, _is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ _is_field: bool,
+ ) -> Result<Self, Error> {
Ok(Self {
// set is_field=false to write type_id like in java
- id: read_data(context, false)?,
+ id: read_data(fory, context, false)?,
})
}
@@ -698,7 +705,7 @@ fn test_consistent_named() {
let data_file_path = get_data_file();
let bytes = fs::read(&data_file_path).unwrap();
let reader = Reader::new(bytes.as_slice());
- let mut context = ReadContext::new(&fory, reader, 5);
+ let mut context = ReadContext::new(reader, 5);
assert_eq!(
fory.deserialize_with_context::<Color>(&mut context)
@@ -732,8 +739,8 @@ fn test_consistent_named() {
my_ext
);
- let mut writer = Writer::default();
- let mut context = WriteContext::new(&fory, &mut writer);
+ let writer = Writer::default();
+ let mut context = WriteContext::new(writer);
fory.serialize_with_context(&color, &mut context);
fory.serialize_with_context(&color, &mut context);
fory.serialize_with_context(&color, &mut context);
diff --git a/rust/tests/tests/test_ext.rs b/rust/tests/tests/test_ext.rs
index 4db19daff..9f43bce5f 100644
--- a/rust/tests/tests/test_ext.rs
+++ b/rust/tests/tests/test_ext.rs
@@ -60,13 +60,17 @@ fn test_use() {
}
impl Serializer for Item {
- fn fory_write_data(&self, context: &mut WriteContext, is_field: bool) {
- write_data(&self.f1, context, is_field);
+ fn fory_write_data(&self, fory: &Fory, context: &mut WriteContext, is_field: bool) {
+ write_data(&self.f1, fory, context, is_field);
}
- fn fory_read_data(context: &mut ReadContext, is_field: bool) -> Result<Self, Error> {
+ fn fory_read_data(
+ fory: &Fory,
+ context: &mut ReadContext,
+ is_field: bool,
+ ) -> Result<Self, Error> {
Ok(Self {
- f1: read_data(context, is_field)?,
+ f1: read_data(fory, context, is_field)?,
f2: 0,
})
}
diff --git a/rust/tests/tests/test_multi_thread.rs b/rust/tests/tests/test_multi_thread.rs
new file mode 100644
index 000000000..d1055caf6
--- /dev/null
+++ b/rust/tests/tests/test_multi_thread.rs
@@ -0,0 +1,102 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use fory_core::Fory;
+use fory_derive::ForyObject;
+use std::collections::HashSet;
+use std::sync::Arc;
+use std::thread;
+
+#[test]
+fn test_simple_multi_thread() {
+ let fory = Arc::new(Fory::default());
+ let src: HashSet<_> = [41, 42, 43, 45, 46, 47].into_iter().collect();
+ // serialize
+ let mut handles = vec![];
+ for item in &src {
+ let fory_clone = Arc::clone(&fory);
+ let item = *item;
+ let handle = thread::spawn(move || fory_clone.serialize(&item));
+ handles.push(handle);
+ }
+ let mut serialized_data = vec![];
+ for handle in handles {
+ let bytes = handle.join().unwrap();
+ serialized_data.push(bytes);
+ }
+ // deserialize
+ let mut dest = HashSet::new();
+ let mut handles = vec![];
+ for bytes in serialized_data {
+ let fory_clone = Arc::clone(&fory);
+ let handle = thread::spawn(move || fory_clone.deserialize::<i32>(&bytes).unwrap());
+ handles.push(handle);
+ }
+ for handle in handles {
+ let value = handle.join().unwrap();
+ dest.insert(value);
+ }
+ // verify
+ assert_eq!(dest, src);
+}
+
+#[test]
+fn test_struct_multi_thread() {
+ #[derive(ForyObject, Debug, PartialEq, Eq, Hash, Clone, Copy)]
+ struct Item1 {
+ f1: i32,
+ }
+ let mut fory = Fory::default();
+ fory.register::<Item1>(101);
+ let fory = Arc::new(fory);
+ let src: HashSet<_> = [
+ Item1 { f1: 42 },
+ Item1 { f1: 43 },
+ Item1 { f1: 45 },
+ Item1 { f1: 46 },
+ Item1 { f1: 47 },
+ ]
+ .into_iter()
+ .collect();
+ // serialize
+ let mut handles = vec![];
+ for item in &src {
+ let fory_clone = Arc::clone(&fory);
+ let item = *item;
+ let handle = thread::spawn(move || fory_clone.serialize(&item));
+ handles.push(handle);
+ }
+ let mut serialized_data = vec![];
+ for handle in handles {
+ let bytes = handle.join().unwrap();
+ serialized_data.push(bytes);
+ }
+ // deserialize
+ let mut dest = HashSet::new();
+ let mut handles = vec![];
+ for bytes in serialized_data {
+ let fory_clone = Arc::clone(&fory);
+ let handle = thread::spawn(move || fory_clone.deserialize::<Item1>(&bytes).unwrap());
+ handles.push(handle);
+ }
+ for handle in handles {
+ let value = handle.join().unwrap();
+ dest.insert(value);
+ }
+ // verify
+ assert_eq!(dest, src);
+}
diff --git a/rust/tests/tests/test_ref_resolver.rs b/rust/tests/tests/test_ref_resolver.rs
index 22f6f585c..5dfca17b5 100644
--- a/rust/tests/tests/test_ref_resolver.rs
+++ b/rust/tests/tests/test_ref_resolver.rs
@@ -88,7 +88,7 @@ fn test_ref_writer_clear() {
assert!(!ref_writer.try_write_rc_ref(&mut writer, &rc));
// Clear the writer
- ref_writer.clear();
+ ref_writer.reset();
// After clearing, should register as new reference again
assert!(!ref_writer.try_write_rc_ref(&mut writer, &rc));
@@ -104,7 +104,7 @@ fn test_ref_reader_clear() {
assert!(ref_reader.get_rc_ref::<String>(ref_id).is_some());
// Clear the reader
- ref_reader.clear();
+ ref_reader.reset();
// After clearing, reference should no longer be found
assert!(ref_reader.get_rc_ref::<String>(ref_id).is_none());
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@fory.apache.org
For additional commands, e-mail: commits-help@fory.apache.org