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 d99db756c feat(rust): support btree set and binary heap serialization 
(#2744)
d99db756c is described below

commit d99db756c30ccaa448f861ce75fb11c5c8144ef5
Author: Shawn Yang <[email protected]>
AuthorDate: Fri Oct 10 13:37:37 2025 +0530

    feat(rust): support btree set and binary heap serialization (#2744)
    
    ## Why?
    
    <!-- Describe the purpose of this PR. -->
    
    ## What does this PR do?
    
    support btree set and binary heap serialization
    
    ## 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/README.md                                    |   2 +
 rust/fory-core/src/serializer/{set.rs => heap.rs} |   8 +-
 rust/fory-core/src/serializer/mod.rs              |   1 +
 rust/fory-core/src/serializer/set.rs              |  42 +++++++-
 rust/fory-derive/src/object/util.rs               |   3 +-
 rust/tests/tests/test_collection.rs               | 121 ++++++++++++++++++++++
 6 files changed, 171 insertions(+), 6 deletions(-)

diff --git a/rust/README.md b/rust/README.md
index 4c14189e7..026976d17 100644
--- a/rust/README.md
+++ b/rust/README.md
@@ -753,6 +753,8 @@ assert_eq!(prefs.values().get(0), "en");
 | `HashMap<K, V>`  | Hash map           |
 | `BTreeMap<K, V>` | Ordered map        |
 | `HashSet<T>`     | Hash set           |
+| `BTreeSet<T>`    | Ordered set        |
+| `BinaryHeap<T>`  | Binary heap        |
 | `Option<T>`      | Optional value     |
 
 ### Smart Pointers
diff --git a/rust/fory-core/src/serializer/set.rs 
b/rust/fory-core/src/serializer/heap.rs
similarity index 92%
copy from rust/fory-core/src/serializer/set.rs
copy to rust/fory-core/src/serializer/heap.rs
index c87d8e1b9..6e9d56d45 100644
--- a/rust/fory-core/src/serializer/set.rs
+++ b/rust/fory-core/src/serializer/heap.rs
@@ -25,10 +25,10 @@ use crate::serializer::collection::{
 
 use crate::serializer::{ForyDefault, Serializer};
 use crate::types::TypeId;
-use std::collections::HashSet;
+use std::collections::BinaryHeap;
 use std::mem;
 
-impl<T: Serializer + ForyDefault + Eq + std::hash::Hash> Serializer for 
HashSet<T> {
+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);
     }
@@ -62,8 +62,8 @@ impl<T: Serializer + ForyDefault + Eq + std::hash::Hash> 
Serializer for HashSet<
     }
 }
 
-impl<T> ForyDefault for HashSet<T> {
+impl<T: Ord> ForyDefault for BinaryHeap<T> {
     fn fory_default() -> Self {
-        HashSet::new()
+        BinaryHeap::new()
     }
 }
diff --git a/rust/fory-core/src/serializer/mod.rs 
b/rust/fory-core/src/serializer/mod.rs
index d20359112..10d300c69 100644
--- a/rust/fory-core/src/serializer/mod.rs
+++ b/rust/fory-core/src/serializer/mod.rs
@@ -30,6 +30,7 @@ mod box_;
 pub mod collection;
 mod datetime;
 pub mod enum_;
+mod heap;
 mod list;
 pub mod map;
 mod mutex;
diff --git a/rust/fory-core/src/serializer/set.rs 
b/rust/fory-core/src/serializer/set.rs
index c87d8e1b9..47ebe0b0b 100644
--- a/rust/fory-core/src/serializer/set.rs
+++ b/rust/fory-core/src/serializer/set.rs
@@ -25,7 +25,7 @@ use crate::serializer::collection::{
 
 use crate::serializer::{ForyDefault, Serializer};
 use crate::types::TypeId;
-use std::collections::HashSet;
+use std::collections::{BTreeSet, HashSet};
 use std::mem;
 
 impl<T: Serializer + ForyDefault + Eq + std::hash::Hash> Serializer for 
HashSet<T> {
@@ -67,3 +67,43 @@ impl<T> ForyDefault for HashSet<T> {
         HashSet::new()
     }
 }
+
+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_type_info(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_type_info(context: &mut ReadContext, is_field: bool) {
+        read_collection_type_info(context, is_field, TypeId::SET as u32)
+    }
+
+    fn fory_reserved_space() -> usize {
+        mem::size_of::<i32>()
+    }
+
+    fn fory_get_type_id(_fory: &Fory) -> u32 {
+        TypeId::SET as u32
+    }
+
+    fn fory_type_id_dyn(&self, _fory: &Fory) -> u32 {
+        TypeId::SET as u32
+    }
+
+    fn as_any(&self) -> &dyn std::any::Any {
+        self
+    }
+}
+
+impl<T> ForyDefault for BTreeSet<T> {
+    fn fory_default() -> Self {
+        BTreeSet::new()
+    }
+}
diff --git a/rust/fory-derive/src/object/util.rs 
b/rust/fory-derive/src/object/util.rs
index 40687c96f..6eee2120e 100644
--- a/rust/fory-derive/src/object/util.rs
+++ b/rust/fory-derive/src/object/util.rs
@@ -877,9 +877,10 @@ pub(super) fn get_sort_fields_ts(fields: &[&Field]) -> 
TokenStream {
             } else if ty.starts_with("Vec<")
                 || ty.starts_with("VecDeque<")
                 || ty.starts_with("LinkedList<")
+                || ty.starts_with("BinaryHeap<")
             {
                 collection_fields.push((ident, ty.to_string(), TypeId::LIST as 
u32));
-            } else if ty.starts_with("HashSet<") {
+            } else if ty.starts_with("HashSet<") || 
ty.starts_with("BTreeSet<") {
                 collection_fields.push((ident, ty.to_string(), TypeId::SET as 
u32));
             } else if ty.starts_with("HashMap<") || 
ty.starts_with("BTreeMap<") {
                 map_fields.push((ident, ty.to_string(), TypeId::MAP as u32));
diff --git a/rust/tests/tests/test_collection.rs 
b/rust/tests/tests/test_collection.rs
new file mode 100644
index 000000000..dc370ba36
--- /dev/null
+++ b/rust/tests/tests/test_collection.rs
@@ -0,0 +1,121 @@
+// 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, Serializer};
+use fory_derive::ForyObject;
+use std::collections::{BTreeSet, BinaryHeap, HashSet};
+
+#[test]
+fn test_btreeset_roundtrip() {
+    let fory: Fory = Fory::default();
+
+    let mut original = BTreeSet::new();
+    original.insert(1);
+    original.insert(2);
+    original.insert(3);
+
+    let trait_obj: Box<dyn Serializer> = Box::new(original.clone());
+    let serialized = fory.serialize(&trait_obj);
+
+    let deserialized_concrete: BTreeSet<i32> = 
fory.deserialize(&serialized).unwrap();
+
+    assert_eq!(deserialized_concrete.len(), 3);
+    assert!(deserialized_concrete.contains(&1));
+    assert!(deserialized_concrete.contains(&2));
+    assert!(deserialized_concrete.contains(&3));
+}
+
+#[test]
+fn test_binaryheap_roundtrip() {
+    let fory: Fory = Fory::default();
+
+    let mut original = BinaryHeap::new();
+    original.push(10);
+    original.push(20);
+    original.push(15);
+
+    let serialized = fory.serialize(&original);
+    let deserialized_concrete: BinaryHeap<i32> = 
fory.deserialize(&serialized).unwrap();
+
+    assert_eq!(deserialized_concrete.len(), 3);
+    assert_eq!(deserialized_concrete.peek(), Some(&20));
+}
+
+#[derive(ForyObject, Debug, Clone, PartialEq)]
+struct SetContainer {
+    btree_set: BTreeSet<String>,
+    hash_set: HashSet<String>,
+}
+
+#[test]
+fn test_set_container() {
+    let mut fory: Fory = Fory::default();
+    fory.register::<SetContainer>(100);
+
+    let mut btree = BTreeSet::new();
+    btree.insert("apple".to_string());
+    btree.insert("banana".to_string());
+    btree.insert("cherry".to_string());
+
+    let mut hash = HashSet::new();
+    hash.insert("one".to_string());
+    hash.insert("two".to_string());
+    hash.insert("three".to_string());
+
+    let original = SetContainer {
+        btree_set: btree,
+        hash_set: hash,
+    };
+
+    let serialized = fory.serialize(&original);
+    let deserialized: SetContainer = fory.deserialize(&serialized).unwrap();
+
+    assert_eq!(deserialized, original);
+    assert_eq!(deserialized.btree_set.len(), 3);
+    assert!(deserialized.btree_set.contains("apple"));
+    assert!(deserialized.btree_set.contains("banana"));
+    assert!(deserialized.btree_set.contains("cherry"));
+    assert_eq!(deserialized.hash_set.len(), 3);
+    assert!(deserialized.hash_set.contains("one"));
+    assert!(deserialized.hash_set.contains("two"));
+    assert!(deserialized.hash_set.contains("three"));
+}
+
+#[derive(ForyObject, Debug)]
+struct HeapContainer {
+    binary_heap: BinaryHeap<i32>,
+}
+
+#[test]
+fn test_heap_container() {
+    let mut fory: Fory = Fory::default();
+    fory.register::<HeapContainer>(100);
+
+    let mut binary_heap = BinaryHeap::new();
+    binary_heap.push(3);
+    binary_heap.push(1);
+    binary_heap.push(2);
+
+    let original = HeapContainer { binary_heap };
+
+    let serialized = fory.serialize(&original);
+    let deserialized: HeapContainer = fory.deserialize(&serialized).unwrap();
+
+    assert_eq!(deserialized.binary_heap.len(), 3);
+    assert_eq!(deserialized.binary_heap.len(), 3);
+    assert_eq!(deserialized.binary_heap.peek(), Some(&3));
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to