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 c8a5b407e feat(rust): make whether write type/ref compile-time
evaluation (#2871)
c8a5b407e is described below
commit c8a5b407e9188767911b77c1b784f0d9f6b83cd1
Author: Shawn Yang <[email protected]>
AuthorDate: Sun Nov 2 16:46:04 2025 +0800
feat(rust): make whether write type/ref compile-time evaluation (#2871)
## Why?
<!-- Describe the purpose of this PR. -->
## What does this PR do?
make whether write type/ref compile-time evaluation
## Related issues
<!--
Is there any related issue? If this PR closes them you say say
fix/closes:
- #xxxx0
- #xxxx1
- Fixes #xxxx2
-->
## Does this PR introduce any user-facing change?
<!--
If any user-facing interface changes, please [open an
issue](https://github.com/apache/fory/issues/new/choose) describing the
need to do so and update the document if necessary.
Delete section if not applicable.
-->
- [ ] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
## Benchmark
<!--
When the PR has an impact on performance (if you don't know whether the
PR will have an impact on performance, you can submit the PR first, and
if it will have impact on performance, the code reviewer will explain
it), be sure to attach a benchmark data here.
Delete section if not applicable.
-->
---
rust/fory-core/src/serializer/util.rs | 37 +++++++++++++++--------------------
rust/fory-core/src/types.rs | 33 +++++++++++++++++--------------
rust/fory-derive/src/object/read.rs | 2 +-
rust/fory-derive/src/object/write.rs | 4 ++--
4 files changed, 37 insertions(+), 39 deletions(-)
diff --git a/rust/fory-core/src/serializer/util.rs
b/rust/fory-core/src/serializer/util.rs
index 5655719bb..b82ece8df 100644
--- a/rust/fory-core/src/serializer/util.rs
+++ b/rust/fory-core/src/serializer/util.rs
@@ -20,22 +20,10 @@ use crate::error::Error;
use crate::resolver::context::{ReadContext, WriteContext};
use crate::serializer::Serializer;
use crate::types::TypeId;
-use crate::types::{is_user_type, ENUM, NAMED_ENUM};
-
-const NO_REF_FLAG_TYPE_IDS: [u32; 12] = [
- TypeId::BOOL as u32,
- TypeId::INT8 as u32,
- TypeId::INT16 as u32,
- TypeId::INT32 as u32,
- TypeId::INT64 as u32,
- TypeId::FLOAT32 as u32,
- TypeId::FLOAT64 as u32,
- TypeId::U8 as u32,
- TypeId::U16 as u32,
- TypeId::U32 as u32,
- TypeId::U64 as u32,
- TypeId::USIZE as u32,
-];
+use crate::types::{
+ is_user_type, BOOL, ENUM, FLOAT32, FLOAT64, INT16, INT32, INT64, INT8,
NAMED_ENUM, U16, U32,
+ U64, U8, USIZE,
+};
#[inline(always)]
pub(crate) fn read_basic_type_info<T: Serializer>(context: &mut ReadContext)
-> Result<(), Error> {
@@ -53,8 +41,10 @@ pub(crate) fn read_basic_type_info<T: Serializer>(context:
&mut ReadContext) ->
/// According to xlang_serialization_spec.md:
/// - For enums (ENUM/NAMED_ENUM), we should skip writing type info
/// - For structs and ext types, we should write type info
+///
+/// Keep as const fn for compile time evaluation or constant folding
#[inline]
-pub fn field_need_read_type_info(type_id: u32) -> bool {
+pub const fn field_need_read_type_info(type_id: u32) -> bool {
let internal_type_id = type_id & 0xff;
if internal_type_id == ENUM || internal_type_id == NAMED_ENUM {
return false;
@@ -62,21 +52,26 @@ pub fn field_need_read_type_info(type_id: u32) -> bool {
is_user_type(internal_type_id)
}
-pub fn field_need_write_type_info<T: Serializer>() -> bool {
- let static_type_id = T::fory_static_type_id() as u32;
+/// Keep as const fn for compile time evaluation or constant folding
+pub const fn field_need_write_type_info(static_type_id: TypeId) -> bool {
+ let static_type_id = static_type_id as u32;
if static_type_id == ENUM || static_type_id == NAMED_ENUM {
return false;
}
is_user_type(static_type_id)
}
+/// Keep as const fn for compile time evaluation or constant folding
#[inline]
-pub fn field_need_write_ref_into(type_id: u32, nullable: bool) -> bool {
+pub const fn field_need_write_ref_into(type_id: u32, nullable: bool) -> bool {
if nullable {
return true;
}
let internal_type_id = type_id & 0xff;
- !NO_REF_FLAG_TYPE_IDS.contains(&internal_type_id)
+ !matches!(
+ internal_type_id,
+ BOOL | INT8 | INT16 | INT32 | INT64 | FLOAT32 | FLOAT64 | U8 | U16 |
U32 | U64 | USIZE
+ )
}
#[inline(always)]
diff --git a/rust/fory-core/src/types.rs b/rust/fory-core/src/types.rs
index 6577d1ab5..f736d70b7 100644
--- a/rust/fory-core/src/types.rs
+++ b/rust/fory-core/src/types.rs
@@ -261,8 +261,9 @@ pub static PRIMITIVE_ARRAY_TYPE_MAP: &[(&str, u32, &str)] =
&[
("usize", TypeId::USIZE_ARRAY as u32, "Vec<usize>"),
];
+/// Keep as const fn for compile time evaluation or constant folding
#[inline(always)]
-pub fn is_primitive_type_id(type_id: TypeId) -> bool {
+pub const fn is_primitive_type_id(type_id: TypeId) -> bool {
matches!(
type_id,
TypeId::BOOL
@@ -280,26 +281,27 @@ pub fn is_primitive_type_id(type_id: TypeId) -> bool {
)
}
+/// Keep as const fn for compile time evaluation or constant folding
#[inline(always)]
-pub fn is_internal_type(type_id: u32) -> bool {
+pub const fn is_internal_type(type_id: u32) -> bool {
if type_id == 0 || type_id >= TypeId::UNKNOWN as u32 {
return false;
}
- let excluded = [
- TypeId::ENUM as u32,
- TypeId::NAMED_ENUM as u32,
- TypeId::STRUCT as u32,
- TypeId::COMPATIBLE_STRUCT as u32,
- TypeId::NAMED_STRUCT as u32,
- TypeId::NAMED_COMPATIBLE_STRUCT as u32,
- TypeId::EXT as u32,
- TypeId::NAMED_EXT as u32,
- ];
- !excluded.contains(&type_id)
+ !matches!(
+ type_id,
+ ENUM | NAMED_ENUM
+ | STRUCT
+ | COMPATIBLE_STRUCT
+ | NAMED_STRUCT
+ | NAMED_COMPATIBLE_STRUCT
+ | EXT
+ | NAMED_EXT
+ )
}
+/// Keep as const fn for compile time evaluation or constant folding
#[inline(always)]
-pub(crate) fn need_to_write_type_for_field(type_id: TypeId) -> bool {
+pub(crate) const fn need_to_write_type_for_field(type_id: TypeId) -> bool {
matches!(
type_id,
TypeId::STRUCT
@@ -312,8 +314,9 @@ pub(crate) fn need_to_write_type_for_field(type_id: TypeId)
-> bool {
)
}
+/// Keep as const fn for compile time evaluation or constant folding
#[inline(always)]
-pub(crate) fn is_user_type(type_id: u32) -> bool {
+pub(crate) const fn is_user_type(type_id: u32) -> bool {
matches!(
type_id,
ENUM | NAMED_ENUM
diff --git a/rust/fory-derive/src/object/read.rs
b/rust/fory-derive/src/object/read.rs
index fc8573173..ec92209e7 100644
--- a/rust/fory-derive/src/object/read.rs
+++ b/rust/fory-derive/src/object/read.rs
@@ -199,7 +199,7 @@ pub fn gen_read_field(field: &Field, private_ident: &Ident)
-> TokenStream {
} else {
// Custom types (struct/enum/ext) - need runtime check for
enums
quote! {
- let need_type_info =
fory_core::serializer::util::field_need_write_type_info::<#ty>();
+ let need_type_info =
fory_core::serializer::util::field_need_write_type_info(<#ty as
fory_core::Serializer>::fory_static_type_id());
let #private_ident = <#ty as
fory_core::Serializer>::fory_read(context, true, need_type_info)?;
}
}
diff --git a/rust/fory-derive/src/object/write.rs
b/rust/fory-derive/src/object/write.rs
index 4c1b505bc..fd9981bb5 100644
--- a/rust/fory-derive/src/object/write.rs
+++ b/rust/fory-derive/src/object/write.rs
@@ -208,12 +208,12 @@ pub fn gen_write_field(field: &Field, ident: &Ident,
use_self: bool) -> TokenStr
}
} else if skip_ref_flag {
quote! {
- let need_type_info =
fory_core::serializer::util::field_need_write_type_info::<#ty>();
+ let need_type_info =
fory_core::serializer::util::field_need_write_type_info(<#ty as
fory_core::Serializer>::fory_static_type_id());
<#ty as fory_core::Serializer>::fory_write(&#value_ts,
context, false, need_type_info, false)?;
}
} else {
quote! {
- let need_type_info =
fory_core::serializer::util::field_need_write_type_info::<#ty>();
+ let need_type_info =
fory_core::serializer::util::field_need_write_type_info(<#ty as
fory_core::Serializer>::fory_static_type_id());
<#ty as fory_core::Serializer>::fory_write(&#value_ts,
context, true, need_type_info, false)?;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]