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 6bf6a5935 feat(rust): support VecDeque/LinkedList serialization (#2741)
6bf6a5935 is described below

commit 6bf6a593502097b12997e1c8ba0cbe29adbcb7a2
Author: Shawn Yang <[email protected]>
AuthorDate: Fri Oct 10 10:59:13 2025 +0530

    feat(rust): support VecDeque/LinkedList serialization (#2741)
    
    ## Why?
    
    <!-- Describe the purpose of this PR. -->
    
    ## What does this PR do?
    
    support VecDeque/LinkedList 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                        |  24 +++---
 rust/fory-core/src/lib.rs             |  20 +++++
 rust/fory-core/src/serializer/list.rs |  81 ++++++++++++++++++++
 rust/fory-derive/src/object/util.rs   |   5 +-
 rust/tests/tests/test_list.rs         | 139 ++++++++++++++++++++++++++++++++++
 5 files changed, 257 insertions(+), 12 deletions(-)

diff --git a/rust/README.md b/rust/README.md
index 4bc402dff..4c14189e7 100644
--- a/rust/README.md
+++ b/rust/README.md
@@ -88,7 +88,7 @@ use fory::{Fory, Error};
 use fory::ForyObject;
 use std::collections::HashMap;
 
-#[derive(ForyObject, Debug, PartialEq, Default)]
+#[derive(ForyObject, Debug, PartialEq)]
 struct Person {
     name: String,
     age: i32,
@@ -97,7 +97,7 @@ struct Person {
     metadata: HashMap<String, String>,
 }
 
-#[derive(ForyObject, Debug, PartialEq, Default)]
+#[derive(ForyObject, Debug, PartialEq)]
 struct Address {
     street: String,
     city: String,
@@ -567,7 +567,7 @@ Apache Fory™ supports enums without data payloads (C-style 
enums). Each varian
 ```rust
 use fory::ForyObject;
 
-#[derive(ForyObject, Debug, PartialEq, Default)]
+#[derive(Default, ForyObject, Debug, PartialEq)]
 enum Status {
     #[default]
     Pending,
@@ -598,7 +598,7 @@ For types that don't support `#[derive(ForyObject)]`, 
implement the `Serializer`
 use fory::{Fory, ReadContext, WriteContext, Serializer, ForyDefault, Error};
 use std::any::Any;
 
-#[derive(Debug, PartialEq, Default)]
+#[derive(Debug, PartialEq)]
 struct CustomType {
     value: i32,
     name: String,
@@ -745,13 +745,15 @@ assert_eq!(prefs.values().get(0), "en");
 
 ### Collections
 
-| Rust Type        | Description    |
-| ---------------- | -------------- |
-| `Vec<T>`         | Dynamic array  |
-| `HashMap<K, V>`  | Hash map       |
-| `BTreeMap<K, V>` | Ordered map    |
-| `HashSet<T>`     | Hash set       |
-| `Option<T>`      | Optional value |
+| Rust Type        | Description        |
+| ---------------- | ------------------ |
+| `Vec<T>`         | Dynamic array      |
+| `VecDeque<T>`    | Double-ended queue |
+| `LinkedList<T>`  | Doubly-linked list |
+| `HashMap<K, V>`  | Hash map           |
+| `BTreeMap<K, V>` | Ordered map        |
+| `HashSet<T>`     | Hash set           |
+| `Option<T>`      | Optional value     |
 
 ### Smart Pointers
 
diff --git a/rust/fory-core/src/lib.rs b/rust/fory-core/src/lib.rs
index 957bf6dce..a2ea1fe74 100644
--- a/rust/fory-core/src/lib.rs
+++ b/rust/fory-core/src/lib.rs
@@ -145,10 +145,30 @@
 //! use fory_core::error::Error;
 //! use fory_core::types::Mode;
 //! use fory_core::row::{to_row, from_row};
+//! use std::collections::HashMap;
 //!
 //! // Create a Fory instance
 //! let mut fory = Fory::default().mode(Mode::Compatible);
 //!
+//! // Serialize String
+//! let text = String::from("Hello, Fory!");
+//! let serialized_str = fory.serialize(&text);
+//! let deserialized_str: String = fory.deserialize(&serialized_str).unwrap();
+//! assert_eq!(text, deserialized_str);
+//!
+//! // Serialize Vec
+//! let vec_data = vec![1, 2, 3, 4, 5];
+//! let serialized_vec = fory.serialize(&vec_data);
+//! let deserialized_vec: Vec<i32> = 
fory.deserialize(&serialized_vec).unwrap();
+//! assert_eq!(vec_data, deserialized_vec);
+//!
+//! // Serialize HashMap
+//! let mut map = HashMap::new();
+//! map.insert("key1".to_string(), 100);
+//! map.insert("key2".to_string(), 200);
+//! let serialized_map = fory.serialize(&map);
+//! let deserialized_map: HashMap<String, i32> = 
fory.deserialize(&serialized_map).unwrap();
+//! assert_eq!(map, deserialized_map);
 //! // Register types for object serialization
 //! // fory.register::<MyStruct>(type_id);
 //!
diff --git a/rust/fory-core/src/serializer/list.rs 
b/rust/fory-core/src/serializer/list.rs
index 23c51823d..f60d9641f 100644
--- a/rust/fory-core/src/serializer/list.rs
+++ b/rust/fory-core/src/serializer/list.rs
@@ -23,6 +23,7 @@ use crate::serializer::primitive_list;
 use crate::serializer::{ForyDefault, Serializer};
 use crate::types::TypeId;
 use std::any::TypeId as RsTypeId;
+use std::collections::{LinkedList, VecDeque};
 use std::mem;
 
 use super::collection::{
@@ -113,3 +114,83 @@ impl<T> ForyDefault for Vec<T> {
         Vec::new()
     }
 }
+
+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_type_info(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_type_info(context: &mut ReadContext, is_field: bool) {
+        read_collection_type_info(context, is_field, TypeId::LIST as u32);
+    }
+
+    fn fory_reserved_space() -> usize {
+        mem::size_of::<u32>()
+    }
+
+    fn fory_get_type_id(_fory: &Fory) -> u32 {
+        TypeId::LIST as u32
+    }
+
+    fn fory_type_id_dyn(&self, _fory: &Fory) -> u32 {
+        TypeId::LIST as u32
+    }
+
+    fn as_any(&self) -> &dyn std::any::Any {
+        self
+    }
+}
+
+impl<T> ForyDefault for VecDeque<T> {
+    fn fory_default() -> Self {
+        VecDeque::new()
+    }
+}
+
+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_type_info(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_type_info(context: &mut ReadContext, is_field: bool) {
+        read_collection_type_info(context, is_field, TypeId::LIST as u32);
+    }
+
+    fn fory_reserved_space() -> usize {
+        mem::size_of::<u32>()
+    }
+
+    fn fory_get_type_id(_fory: &Fory) -> u32 {
+        TypeId::LIST as u32
+    }
+
+    fn fory_type_id_dyn(&self, _fory: &Fory) -> u32 {
+        TypeId::LIST as u32
+    }
+
+    fn as_any(&self) -> &dyn std::any::Any {
+        self
+    }
+}
+
+impl<T> ForyDefault for LinkedList<T> {
+    fn fory_default() -> Self {
+        LinkedList::new()
+    }
+}
diff --git a/rust/fory-derive/src/object/util.rs 
b/rust/fory-derive/src/object/util.rs
index 0330ab8df..655bbfa91 100644
--- a/rust/fory-derive/src/object/util.rs
+++ b/rust/fory-derive/src/object/util.rs
@@ -874,7 +874,10 @@ pub(super) fn get_sort_fields_ts(fields: &[&Field]) -> 
TokenStream {
                     ("Vec<f64>", TypeId::FLOAT64_ARRAY),
                 );
                 final_fields.push((ident, ty.to_string(), type_id));
-            } else if ty.starts_with("Vec<") {
+            } else if ty.starts_with("Vec<")
+                || ty.starts_with("VecDeque<")
+                || ty.starts_with("LinkedList<")
+            {
                 collection_fields.push((ident, ty.to_string(), TypeId::LIST as 
u32));
             } else if ty.starts_with("HashSet<") {
                 collection_fields.push((ident, ty.to_string(), TypeId::SET as 
u32));
diff --git a/rust/tests/tests/test_list.rs b/rust/tests/tests/test_list.rs
new file mode 100644
index 000000000..218b3d61e
--- /dev/null
+++ b/rust/tests/tests/test_list.rs
@@ -0,0 +1,139 @@
+// 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::Fory;
+use fory_derive::ForyObject;
+use std::collections::{LinkedList, VecDeque};
+
+#[test]
+fn test_vecdeque_i32() {
+    let fory = Fory::default();
+    let mut deque = VecDeque::new();
+    deque.push_back(1);
+    deque.push_back(2);
+    deque.push_back(3);
+    let bin = fory.serialize(&deque);
+    let obj: VecDeque<i32> = fory.deserialize(&bin).expect("deserialize");
+    assert_eq!(deque, obj);
+}
+
+#[test]
+fn test_vecdeque_empty() {
+    let fory = Fory::default();
+    let deque: VecDeque<i32> = VecDeque::new();
+    let bin = fory.serialize(&deque);
+    let obj: VecDeque<i32> = fory.deserialize(&bin).expect("deserialize");
+    assert_eq!(deque, obj);
+}
+
+#[test]
+fn test_vecdeque_string() {
+    let fory = Fory::default();
+    let mut deque = VecDeque::new();
+    deque.push_back("hello".to_string());
+    deque.push_back("world".to_string());
+    let bin = fory.serialize(&deque);
+    let obj: VecDeque<String> = fory.deserialize(&bin).expect("deserialize");
+    assert_eq!(deque, obj);
+}
+
+#[test]
+fn test_vecdeque_f64() {
+    let fory = Fory::default();
+    let mut deque = VecDeque::new();
+    deque.push_back(1.5);
+    deque.push_back(2.5);
+    deque.push_back(3.5);
+    let bin = fory.serialize(&deque);
+    let obj: VecDeque<f64> = fory.deserialize(&bin).expect("deserialize");
+    assert_eq!(deque, obj);
+}
+
+#[test]
+fn test_linkedlist_i32() {
+    let fory = Fory::default();
+    let mut list = LinkedList::new();
+    list.push_back(1);
+    list.push_back(2);
+    list.push_back(3);
+    let bin = fory.serialize(&list);
+    let obj: LinkedList<i32> = fory.deserialize(&bin).expect("deserialize");
+    assert_eq!(list, obj);
+}
+
+#[test]
+fn test_linkedlist_empty() {
+    let fory = Fory::default();
+    let list: LinkedList<i32> = LinkedList::new();
+    let bin = fory.serialize(&list);
+    let obj: LinkedList<i32> = fory.deserialize(&bin).expect("deserialize");
+    assert_eq!(list, obj);
+}
+
+#[test]
+fn test_linkedlist_string() {
+    let fory = Fory::default();
+    let mut list = LinkedList::new();
+    list.push_back("foo".to_string());
+    list.push_back("bar".to_string());
+    let bin = fory.serialize(&list);
+    let obj: LinkedList<String> = fory.deserialize(&bin).expect("deserialize");
+    assert_eq!(list, obj);
+}
+
+#[test]
+fn test_linkedlist_bool() {
+    let fory = Fory::default();
+    let mut list = LinkedList::new();
+    list.push_back(true);
+    list.push_back(false);
+    list.push_back(true);
+    let bin = fory.serialize(&list);
+    let obj: LinkedList<bool> = fory.deserialize(&bin).expect("deserialize");
+    assert_eq!(list, obj);
+}
+
+#[derive(ForyObject, PartialEq, Debug)]
+struct CollectionStruct {
+    vec_field: Vec<i32>,
+    deque_field: VecDeque<String>,
+    list_field: LinkedList<bool>,
+}
+
+#[test]
+fn test_struct_with_collections() {
+    let mut fory = Fory::default();
+    fory.register_by_name::<CollectionStruct>("CollectionStruct");
+
+    let mut deque = VecDeque::new();
+    deque.push_back("hello".to_string());
+    deque.push_back("world".to_string());
+
+    let mut list = LinkedList::new();
+    list.push_back(true);
+    list.push_back(false);
+
+    let data = CollectionStruct {
+        vec_field: vec![1, 2, 3],
+        deque_field: deque,
+        list_field: list,
+    };
+
+    let bin = fory.serialize(&data);
+    let obj: CollectionStruct = fory.deserialize(&bin).expect("deserialize");
+    assert_eq!(data, obj);
+}


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

Reply via email to