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 55d07f769 feat(rust): support reference tracking for rust Rc/Arc 
(#2678)
55d07f769 is described below

commit 55d07f7691fdf79197a107a443e80f63fb0a2bb0
Author: Shawn Yang <[email protected]>
AuthorDate: Sun Sep 28 08:03:56 2025 +0800

    feat(rust): support reference tracking for rust Rc/Arc (#2678)
    
    ## Why?
    
    <!-- Describe the purpose of this PR. -->
    
    ## What does this PR do?
    
    This PR supports reference tracking for rust `Rc/Arc`. `Weak` is not
    supported yet, this PR doesn't support circular reference for now.
    
    
    ## Related issues
    
    Closes #2621
    
    ## 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/resolver/context.rs      |   5 +
 rust/fory-core/src/resolver/mod.rs          |   1 +
 rust/fory-core/src/resolver/ref_resolver.rs | 393 ++++++++++++++++++++++++++++
 rust/fory-core/src/serializer/arc.rs        |  83 ++++++
 rust/fory-core/src/serializer/mod.rs        |  14 +-
 rust/fory-core/src/serializer/rc.rs         |  83 ++++++
 rust/tests/tests/test_complex_refs.rs       | 139 ++++++++++
 rust/tests/tests/test_rc_arc.rs             | 366 ++++++++++++++++++++++++++
 rust/tests/tests/test_ref_resolver.rs       | 129 +++++++++
 9 files changed, 1212 insertions(+), 1 deletion(-)

diff --git a/rust/fory-core/src/resolver/context.rs 
b/rust/fory-core/src/resolver/context.rs
index 3d4f27294..eca165b35 100644
--- a/rust/fory-core/src/resolver/context.rs
+++ b/rust/fory-core/src/resolver/context.rs
@@ -22,6 +22,7 @@ use anyhow::anyhow;
 
 use crate::meta::TypeMeta;
 use crate::resolver::meta_resolver::{MetaReaderResolver, MetaWriterResolver};
+use crate::resolver::ref_resolver::{RefReader, RefWriter};
 use std::rc::Rc;
 
 pub struct WriteContext<'se> {
@@ -29,6 +30,7 @@ pub struct WriteContext<'se> {
     pub tags: Vec<&'static str>,
     fory: &'se Fory,
     meta_resolver: MetaWriterResolver<'se>,
+    pub ref_writer: RefWriter,
 }
 
 impl<'se> WriteContext<'se> {
@@ -38,6 +40,7 @@ impl<'se> WriteContext<'se> {
             tags: Vec::new(),
             fory,
             meta_resolver: MetaWriterResolver::default(),
+            ref_writer: RefWriter::new(),
         }
     }
 
@@ -86,6 +89,7 @@ pub struct ReadContext<'de, 'bf: 'de> {
     pub tags: Vec<&'de str>,
     fory: &'de Fory,
     pub meta_resolver: MetaReaderResolver,
+    pub ref_reader: RefReader,
 }
 
 impl<'de, 'bf: 'de> ReadContext<'de, 'bf> {
@@ -95,6 +99,7 @@ impl<'de, 'bf: 'de> ReadContext<'de, 'bf> {
             tags: Vec::new(),
             fory,
             meta_resolver: MetaReaderResolver::default(),
+            ref_reader: RefReader::new(),
         }
     }
 
diff --git a/rust/fory-core/src/resolver/mod.rs 
b/rust/fory-core/src/resolver/mod.rs
index 62c6f31b7..c5d47a4c1 100644
--- a/rust/fory-core/src/resolver/mod.rs
+++ b/rust/fory-core/src/resolver/mod.rs
@@ -18,4 +18,5 @@
 pub mod context;
 pub mod meta_resolver;
 pub mod metastring_resolver;
+pub mod ref_resolver;
 pub mod type_resolver;
diff --git a/rust/fory-core/src/resolver/ref_resolver.rs 
b/rust/fory-core/src/resolver/ref_resolver.rs
new file mode 100644
index 000000000..e7de532c9
--- /dev/null
+++ b/rust/fory-core/src/resolver/ref_resolver.rs
@@ -0,0 +1,393 @@
+// 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 crate::buffer::{Reader, Writer};
+use crate::types::RefFlag;
+use std::any::Any;
+use std::collections::HashMap;
+use std::rc::Rc;
+use std::sync::Arc;
+
+/// Reference writer for tracking shared references during serialization.
+///
+/// RefWriter maintains a mapping from object pointer addresses to reference 
IDs,
+/// allowing the serialization system to detect when the same object is 
encountered
+/// multiple times and write a reference instead of serializing the object 
again.
+/// This enables proper handling of shared references and circular references.
+///
+/// # Examples
+///
+/// ```rust
+/// use fory_core::buffer::Writer;
+/// use fory_core::resolver::ref_resolver::RefWriter;
+/// use std::rc::Rc;
+///
+/// let mut ref_writer = RefWriter::new();
+/// let mut writer = Writer::default();
+/// let rc = Rc::new(42);
+///
+/// // First encounter - returns false, indicating object should be serialized
+/// assert!(!ref_writer.try_write_rc_ref(&mut writer, &rc));
+///
+/// // Second encounter - returns true, indicating reference was written
+/// let rc2 = rc.clone();
+/// assert!(ref_writer.try_write_rc_ref(&mut writer, &rc2));
+/// ```
+#[derive(Default)]
+pub struct RefWriter {
+    /// Maps pointer addresses to reference IDs
+    refs: HashMap<usize, u32>,
+    /// Next reference ID to assign
+    next_ref_id: u32,
+}
+
+impl RefWriter {
+    /// Creates a new RefWriter instance.
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    /// Attempt to write a reference for an Rc<T>.
+    ///
+    /// Returns true if a reference was written (indicating this object has 
been
+    /// seen before), false if this is the first occurrence and the object 
should
+    /// be serialized normally.
+    ///
+    /// # Arguments
+    ///
+    /// * `writer` - The writer to write reference information to
+    /// * `rc` - The Rc to check for reference tracking
+    ///
+    /// # Returns
+    ///
+    /// * `true` if a reference was written
+    /// * `false` if this is the first occurrence of the object
+    pub fn try_write_rc_ref<T>(&mut self, writer: &mut Writer, rc: &Rc<T>) -> 
bool {
+        let ptr_addr = Rc::as_ptr(rc) as usize;
+
+        if let Some(&ref_id) = self.refs.get(&ptr_addr) {
+            // This object has been seen before, write a reference
+            writer.i8(RefFlag::Ref as i8);
+            writer.u32(ref_id);
+            true
+        } else {
+            // First time seeing this object, register it and return false
+            let ref_id = self.next_ref_id;
+            self.next_ref_id += 1;
+            self.refs.insert(ptr_addr, ref_id);
+            writer.i8(RefFlag::RefValue as i8);
+            false
+        }
+    }
+
+    /// Attempt to write a reference for an Arc<T>.
+    ///
+    /// Returns true if a reference was written (indicating this object has 
been
+    /// seen before), false if this is the first occurrence and the object 
should
+    /// be serialized normally.
+    ///
+    /// # Arguments
+    ///
+    /// * `writer` - The writer to write reference information to
+    /// * `arc` - The Arc to check for reference tracking
+    ///
+    /// # Returns
+    ///
+    /// * `true` if a reference was written
+    /// * `false` if this is the first occurrence of the object
+    pub fn try_write_arc_ref<T>(&mut self, writer: &mut Writer, arc: &Arc<T>) 
-> bool {
+        let ptr_addr = Arc::as_ptr(arc) as usize;
+
+        if let Some(&ref_id) = self.refs.get(&ptr_addr) {
+            // This object has been seen before, write a reference
+            writer.i8(RefFlag::Ref as i8);
+            writer.u32(ref_id);
+            true
+        } else {
+            // First time seeing this object, register it and return false
+            let ref_id = self.next_ref_id;
+            self.next_ref_id += 1;
+            self.refs.insert(ptr_addr, ref_id);
+            writer.i8(RefFlag::RefValue as i8);
+            false
+        }
+    }
+
+    /// Clear all stored references.
+    ///
+    /// This is useful for reusing the RefWriter for multiple serialization 
operations.
+    pub fn clear(&mut self) {
+        self.refs.clear();
+        self.next_ref_id = 0;
+    }
+}
+
+/// Reference reader for resolving shared references during deserialization.
+///
+/// RefReader maintains a vector of previously deserialized objects that can be
+/// referenced by ID. When a reference is encountered during deserialization,
+/// the RefReader can return the previously deserialized object instead of
+/// deserializing it again.
+///
+/// # Examples
+///
+/// ```rust
+/// use fory_core::resolver::ref_resolver::RefReader;
+/// use std::rc::Rc;
+///
+/// let mut ref_reader = RefReader::new();
+/// let rc = Rc::new(42);
+///
+/// // Store an object for later reference
+/// let ref_id = ref_reader.store_rc_ref(rc.clone());
+///
+/// // Retrieve the object by reference ID
+/// let retrieved = ref_reader.get_rc_ref::<i32>(ref_id).unwrap();
+/// assert!(Rc::ptr_eq(&rc, &retrieved));
+/// ```
+#[derive(Default)]
+pub struct RefReader {
+    /// Vector to store boxed objects for reference resolution
+    refs: Vec<Box<dyn Any>>,
+}
+
+impl RefReader {
+    /// Creates a new RefReader instance.
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    /// Store an Rc<T> for later reference resolution during deserialization.
+    ///
+    /// # Arguments
+    ///
+    /// * `rc` - The Rc to store for later reference
+    ///
+    /// # Returns
+    ///
+    /// The reference ID that can be used to retrieve this object later
+    pub fn store_rc_ref<T: 'static>(&mut self, rc: Rc<T>) -> u32 {
+        let ref_id = self.refs.len() as u32;
+        self.refs.push(Box::new(rc));
+        ref_id
+    }
+
+    /// Store an Arc<T> for later reference resolution during deserialization.
+    ///
+    /// # Arguments
+    ///
+    /// * `arc` - The Arc to store for later reference
+    ///
+    /// # Returns
+    ///
+    /// The reference ID that can be used to retrieve this object later
+    pub fn store_arc_ref<T: 'static>(&mut self, arc: Arc<T>) -> u32 {
+        let ref_id = self.refs.len() as u32;
+        self.refs.push(Box::new(arc));
+        ref_id
+    }
+
+    /// Get an Rc<T> by reference ID during deserialization.
+    ///
+    /// # Arguments
+    ///
+    /// * `ref_id` - The reference ID returned by `store_rc_ref`
+    ///
+    /// # Returns
+    ///
+    /// * `Some(Rc<T>)` if the reference ID is valid and the type matches
+    /// * `None` if the reference ID is invalid or the type doesn't match
+    pub fn get_rc_ref<T: 'static>(&self, ref_id: u32) -> Option<Rc<T>> {
+        let any_box = self.refs.get(ref_id as usize)?;
+        any_box.downcast_ref::<Rc<T>>().cloned()
+    }
+
+    /// Get an Arc<T> by reference ID during deserialization.
+    ///
+    /// # Arguments
+    ///
+    /// * `ref_id` - The reference ID returned by `store_arc_ref`
+    ///
+    /// # Returns
+    ///
+    /// * `Some(Arc<T>)` if the reference ID is valid and the type matches
+    /// * `None` if the reference ID is invalid or the type doesn't match
+    pub fn get_arc_ref<T: 'static>(&self, ref_id: u32) -> Option<Arc<T>> {
+        let any_box = self.refs.get(ref_id as usize)?;
+        any_box.downcast_ref::<Arc<T>>().cloned()
+    }
+
+    /// Read a reference flag and determine what action to take.
+    ///
+    /// # Arguments
+    ///
+    /// * `reader` - The reader to read the reference flag from
+    ///
+    /// # Returns
+    ///
+    /// The RefFlag indicating what type of reference this is
+    ///
+    /// # Panics
+    ///
+    /// Panics if an invalid reference flag value is encountered
+    pub fn read_ref_flag(&self, reader: &mut Reader) -> RefFlag {
+        let flag_value = reader.i8();
+        match flag_value {
+            -3 => RefFlag::Null,
+            -2 => RefFlag::Ref,
+            -1 => RefFlag::NotNullValue,
+            0 => RefFlag::RefValue,
+            _ => panic!("Invalid reference flag: {}", flag_value),
+        }
+    }
+
+    /// Read a reference ID from the reader.
+    ///
+    /// # Arguments
+    ///
+    /// * `reader` - The reader to read the reference ID from
+    ///
+    /// # Returns
+    ///
+    /// The reference ID as a u32
+    pub fn read_ref_id(&self, reader: &mut Reader) -> u32 {
+        reader.u32()
+    }
+
+    /// Clear all stored references.
+    ///
+    /// This is useful for reusing the RefReader for multiple deserialization 
operations.
+    pub fn clear(&mut self) {
+        self.refs.clear();
+    }
+}
+
+/// Legacy RefResolver that combines both reading and writing functionality.
+///
+/// This type is maintained for backward compatibility but it's recommended
+/// to use RefWriter and RefReader separately for better separation of 
concerns.
+///
+/// # Deprecated
+///
+/// Use RefWriter for serialization and RefReader for deserialization instead.
+#[deprecated(note = "Use RefWriter for serialization and RefReader for 
deserialization")]
+#[derive(Default)]
+pub struct RefResolver {
+    /// Maps pointer addresses to reference IDs for serialization
+    write_refs: HashMap<usize, u32>,
+    /// Vector to store boxed objects for deserialization
+    read_refs: Vec<Box<dyn Any>>,
+    /// Next reference ID to assign
+    next_ref_id: u32,
+}
+
+#[allow(deprecated)]
+impl RefResolver {
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    /// Attempt to write a reference for an Rc<T>. Returns true if reference 
was written,
+    /// false if this is the first occurrence and should be serialized 
normally.
+    pub fn try_write_rc_ref<T>(&mut self, writer: &mut Writer, rc: &Rc<T>) -> 
bool {
+        let ptr_addr = Rc::as_ptr(rc) as usize;
+
+        if let Some(&ref_id) = self.write_refs.get(&ptr_addr) {
+            // This object has been seen before, write a reference
+            writer.i8(RefFlag::Ref as i8);
+            writer.u32(ref_id);
+            true
+        } else {
+            // First time seeing this object, register it and return false
+            let ref_id = self.next_ref_id;
+            self.next_ref_id += 1;
+            self.write_refs.insert(ptr_addr, ref_id);
+            writer.i8(RefFlag::RefValue as i8);
+            false
+        }
+    }
+
+    /// Attempt to write a reference for an Arc<T>. Returns true if reference 
was written,
+    /// false if this is the first occurrence and should be serialized 
normally.
+    pub fn try_write_arc_ref<T>(&mut self, writer: &mut Writer, arc: &Arc<T>) 
-> bool {
+        let ptr_addr = Arc::as_ptr(arc) as usize;
+
+        if let Some(&ref_id) = self.write_refs.get(&ptr_addr) {
+            // This object has been seen before, write a reference
+            writer.i8(RefFlag::Ref as i8);
+            writer.u32(ref_id);
+            true
+        } else {
+            // First time seeing this object, register it and return false
+            let ref_id = self.next_ref_id;
+            self.next_ref_id += 1;
+            self.write_refs.insert(ptr_addr, ref_id);
+            writer.i8(RefFlag::RefValue as i8);
+            false
+        }
+    }
+
+    /// Store an Rc<T> for later reference resolution during deserialization
+    pub fn store_rc_ref<T: 'static>(&mut self, rc: Rc<T>) -> u32 {
+        let ref_id = self.read_refs.len() as u32;
+        self.read_refs.push(Box::new(rc));
+        ref_id
+    }
+
+    /// Store an Arc<T> for later reference resolution during deserialization
+    pub fn store_arc_ref<T: 'static>(&mut self, arc: Arc<T>) -> u32 {
+        let ref_id = self.read_refs.len() as u32;
+        self.read_refs.push(Box::new(arc));
+        ref_id
+    }
+
+    /// Get an Rc<T> by reference ID during deserialization
+    pub fn get_rc_ref<T: 'static>(&self, ref_id: u32) -> Option<Rc<T>> {
+        let any_box = self.read_refs.get(ref_id as usize)?;
+        any_box.downcast_ref::<Rc<T>>().cloned()
+    }
+
+    /// Get an Arc<T> by reference ID during deserialization
+    pub fn get_arc_ref<T: 'static>(&self, ref_id: u32) -> Option<Arc<T>> {
+        let any_box = self.read_refs.get(ref_id as usize)?;
+        any_box.downcast_ref::<Arc<T>>().cloned()
+    }
+
+    /// Read a reference flag and determine what action to take
+    pub fn read_ref_flag(&self, reader: &mut Reader) -> RefFlag {
+        let flag_value = reader.i8();
+        match flag_value {
+            -3 => RefFlag::Null,
+            -2 => RefFlag::Ref,
+            -1 => RefFlag::NotNullValue,
+            0 => RefFlag::RefValue,
+            _ => panic!("Invalid reference flag: {}", flag_value),
+        }
+    }
+
+    /// Read a reference ID
+    pub fn read_ref_id(&self, reader: &mut Reader) -> u32 {
+        reader.u32()
+    }
+
+    /// Clear all stored references (useful for reusing the resolver)
+    pub fn clear(&mut self) {
+        self.write_refs.clear();
+        self.read_refs.clear();
+        self.next_ref_id = 0;
+    }
+}
diff --git a/rust/fory-core/src/serializer/arc.rs 
b/rust/fory-core/src/serializer/arc.rs
new file mode 100644
index 000000000..68fc7084d
--- /dev/null
+++ b/rust/fory-core/src/serializer/arc.rs
@@ -0,0 +1,83 @@
+// 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 crate::error::Error;
+use crate::fory::Fory;
+use crate::resolver::context::{ReadContext, WriteContext};
+use crate::serializer::Serializer;
+use crate::types::{ForyGeneralList, RefFlag};
+use anyhow::anyhow;
+use std::sync::Arc;
+
+impl<T: Serializer + Send + Sync + 'static> Serializer for Arc<T> {
+    fn read(context: &mut ReadContext) -> Result<Self, Error> {
+        let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader);
+
+        match ref_flag {
+            RefFlag::Null => Err(anyhow!("Arc cannot be null").into()),
+            RefFlag::Ref => {
+                let ref_id = context.ref_reader.read_ref_id(&mut 
context.reader);
+                context
+                    .ref_reader
+                    .get_arc_ref::<T>(ref_id)
+                    .ok_or_else(|| anyhow!("Arc reference {} not found", 
ref_id).into())
+            }
+            RefFlag::NotNullValue => {
+                let inner = T::read(context)?;
+                Ok(Arc::new(inner))
+            }
+            RefFlag::RefValue => {
+                let inner = T::read(context)?;
+                let arc = Arc::new(inner);
+                context.ref_reader.store_arc_ref(arc.clone());
+                Ok(arc)
+            }
+        }
+    }
+
+    fn read_type_info(context: &mut ReadContext, is_field: bool) {
+        T::read_type_info(context, is_field);
+    }
+
+    fn write(&self, context: &mut WriteContext, is_field: bool) {
+        if !context.ref_writer.try_write_arc_ref(context.writer, self) {
+            T::write(self.as_ref(), context, is_field);
+        }
+    }
+
+    fn write_type_info(context: &mut WriteContext, is_field: bool) {
+        T::write_type_info(context, is_field);
+    }
+
+    fn reserved_space() -> usize {
+        T::reserved_space()
+    }
+
+    fn get_type_id(fory: &Fory) -> u32 {
+        T::get_type_id(fory)
+    }
+
+    fn is_option() -> bool {
+        false
+    }
+
+    fn is_none(&self) -> bool {
+        false
+    }
+}
+
+impl<T: Serializer + Send + Sync> ForyGeneralList for Arc<T> {}
diff --git a/rust/fory-core/src/serializer/mod.rs 
b/rust/fory-core/src/serializer/mod.rs
index b90046849..7a8c19166 100644
--- a/rust/fory-core/src/serializer/mod.rs
+++ b/rust/fory-core/src/serializer/mod.rs
@@ -21,6 +21,7 @@ use crate::resolver::context::{ReadContext, WriteContext};
 use crate::types::{Mode, RefFlag, PRIMITIVE_TYPES};
 
 mod any;
+mod arc;
 mod bool;
 mod box_;
 pub mod collection;
@@ -31,6 +32,7 @@ pub mod map;
 mod number;
 mod option;
 mod primitive_list;
+mod rc;
 mod set;
 pub mod skip;
 mod string;
@@ -71,8 +73,18 @@ pub fn read_data<T: Serializer + Default>(
                 T::read_type_info(context, is_field);
             }
             T::read(context)
+        } else if ref_flag == (RefFlag::RefValue as i8) {
+            // First time seeing this referenceable object
+            if !skip_type_info {
+                T::read_type_info(context, is_field);
+            }
+            T::read(context)
+        } 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
+            Ok(T::default())
         } else {
-            unimplemented!()
+            unimplemented!("Unknown ref flag: {}", ref_flag)
         }
     } else {
         if !skip_type_info {
diff --git a/rust/fory-core/src/serializer/rc.rs 
b/rust/fory-core/src/serializer/rc.rs
new file mode 100644
index 000000000..3078bf944
--- /dev/null
+++ b/rust/fory-core/src/serializer/rc.rs
@@ -0,0 +1,83 @@
+// 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 crate::error::Error;
+use crate::fory::Fory;
+use crate::resolver::context::{ReadContext, WriteContext};
+use crate::serializer::Serializer;
+use crate::types::{ForyGeneralList, RefFlag};
+use anyhow::anyhow;
+use std::rc::Rc;
+
+impl<T: Serializer + 'static> Serializer for Rc<T> {
+    fn read(context: &mut ReadContext) -> Result<Self, Error> {
+        let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader);
+
+        match ref_flag {
+            RefFlag::Null => Err(anyhow!("Rc cannot be null").into()),
+            RefFlag::Ref => {
+                let ref_id = context.ref_reader.read_ref_id(&mut 
context.reader);
+                context
+                    .ref_reader
+                    .get_rc_ref::<T>(ref_id)
+                    .ok_or_else(|| anyhow!("Rc reference {} not found", 
ref_id).into())
+            }
+            RefFlag::NotNullValue => {
+                let inner = T::read(context)?;
+                Ok(Rc::new(inner))
+            }
+            RefFlag::RefValue => {
+                let inner = T::read(context)?;
+                let rc = Rc::new(inner);
+                context.ref_reader.store_rc_ref(rc.clone());
+                Ok(rc)
+            }
+        }
+    }
+
+    fn read_type_info(context: &mut ReadContext, is_field: bool) {
+        T::read_type_info(context, is_field);
+    }
+
+    fn write(&self, context: &mut WriteContext, is_field: bool) {
+        if !context.ref_writer.try_write_rc_ref(context.writer, self) {
+            T::write(self.as_ref(), context, is_field);
+        }
+    }
+
+    fn write_type_info(context: &mut WriteContext, is_field: bool) {
+        T::write_type_info(context, is_field);
+    }
+
+    fn reserved_space() -> usize {
+        T::reserved_space()
+    }
+
+    fn get_type_id(fory: &Fory) -> u32 {
+        T::get_type_id(fory)
+    }
+
+    fn is_option() -> bool {
+        false
+    }
+
+    fn is_none(&self) -> bool {
+        false
+    }
+}
+
+impl<T: Serializer> ForyGeneralList for Rc<T> {}
diff --git a/rust/tests/tests/test_complex_refs.rs 
b/rust/tests/tests/test_complex_refs.rs
new file mode 100644
index 000000000..a26e5e764
--- /dev/null
+++ b/rust/tests/tests/test_complex_refs.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.
+
+//! Tests for shared reference handling in Fury Rust
+
+use fory_core::fory::Fory;
+use std::rc::Rc;
+use std::sync::Arc;
+
+#[test]
+fn test_rc_shared_in_nested_vec() {
+    let fury = Fory::default();
+
+    let shared1 = Rc::new(String::from("shared_1"));
+    let shared2 = Rc::new(String::from("shared_2"));
+
+    // Create a nested structure where the same Rc appears multiple times
+    let nested = vec![
+        vec![shared1.clone(), shared2.clone()],
+        vec![shared1.clone(), shared2.clone()],
+        vec![shared1.clone()],
+    ];
+
+    let serialized = fury.serialize(&nested);
+    let deserialized: Vec<Vec<Rc<String>>> = 
fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(deserialized.len(), 3);
+    assert_eq!(deserialized[0].len(), 2);
+    assert_eq!(deserialized[1].len(), 2);
+    assert_eq!(deserialized[2].len(), 1);
+
+    // Verify that all references to the same object are preserved as shared
+    assert!(Rc::ptr_eq(&deserialized[0][0], &deserialized[1][0]));
+    assert!(Rc::ptr_eq(&deserialized[0][0], &deserialized[2][0]));
+    assert!(Rc::ptr_eq(&deserialized[0][1], &deserialized[1][1]));
+
+    // Verify values
+    assert_eq!(*deserialized[0][0], "shared_1");
+    assert_eq!(*deserialized[0][1], "shared_2");
+}
+
+#[test]
+fn test_arc_shared_in_nested_vec() {
+    let fury = Fory::default();
+
+    let shared1 = Arc::new(String::from("shared_1"));
+    let shared2 = Arc::new(String::from("shared_2"));
+
+    // Create a nested structure where the same Arc appears multiple times
+    let nested = vec![
+        vec![shared1.clone(), shared2.clone()],
+        vec![shared1.clone(), shared2.clone()],
+        vec![shared1.clone()],
+    ];
+
+    let serialized = fury.serialize(&nested);
+    let deserialized: Vec<Vec<Arc<String>>> = 
fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(deserialized.len(), 3);
+    assert_eq!(deserialized[0].len(), 2);
+    assert_eq!(deserialized[1].len(), 2);
+    assert_eq!(deserialized[2].len(), 1);
+
+    // Verify that all references to the same object are preserved as shared
+    assert!(Arc::ptr_eq(&deserialized[0][0], &deserialized[1][0]));
+    assert!(Arc::ptr_eq(&deserialized[0][0], &deserialized[2][0]));
+    assert!(Arc::ptr_eq(&deserialized[0][1], &deserialized[1][1]));
+
+    // Verify values
+    assert_eq!(*deserialized[0][0], "shared_1");
+    assert_eq!(*deserialized[0][1], "shared_2");
+}
+
+#[test]
+fn test_mixed_rc_arc_sharing() {
+    let fury = Fory::default();
+
+    // Test both Rc and Arc sharing within the same structure
+    let shared_rc = Rc::new(42i32);
+    let shared_arc = Arc::new(String::from("shared"));
+
+    // Create vectors that mix Rc and Arc types
+    let rc_vec = vec![shared_rc.clone(), shared_rc.clone()];
+    let arc_vec = vec![shared_arc.clone(), shared_arc.clone()];
+
+    let serialized_rc = fury.serialize(&rc_vec);
+    let serialized_arc = fury.serialize(&arc_vec);
+
+    let deserialized_rc: Vec<Rc<i32>> = 
fury.deserialize(&serialized_rc).unwrap();
+    let deserialized_arc: Vec<Arc<String>> = 
fury.deserialize(&serialized_arc).unwrap();
+
+    // Verify Rc sharing
+    assert!(Rc::ptr_eq(&deserialized_rc[0], &deserialized_rc[1]));
+    assert_eq!(*deserialized_rc[0], 42);
+
+    // Verify Arc sharing
+    assert!(Arc::ptr_eq(&deserialized_arc[0], &deserialized_arc[1]));
+    assert_eq!(*deserialized_arc[0], "shared");
+}
+
+#[test]
+fn test_deep_sharing_stress_test() {
+    let fury = Fory::default();
+
+    // Create a stress test with deep nesting and many shared references
+    let shared = Rc::new(String::from("deep_shared"));
+
+    let deep_structure = vec![
+        vec![vec![shared.clone()]],
+        vec![vec![shared.clone()]],
+        vec![vec![shared.clone()]],
+    ];
+
+    let serialized = fury.serialize(&deep_structure);
+    let deserialized: Vec<Vec<Vec<Rc<String>>>> = 
fury.deserialize(&serialized).unwrap();
+
+    // Verify structure
+    assert_eq!(deserialized.len(), 3);
+    assert_eq!(deserialized[0][0][0].as_str(), "deep_shared");
+
+    // Verify all deeply nested references are shared
+    assert!(Rc::ptr_eq(&deserialized[0][0][0], &deserialized[1][0][0]));
+    assert!(Rc::ptr_eq(&deserialized[1][0][0], &deserialized[2][0][0]));
+    assert!(Rc::ptr_eq(&deserialized[0][0][0], &deserialized[2][0][0]));
+}
diff --git a/rust/tests/tests/test_rc_arc.rs b/rust/tests/tests/test_rc_arc.rs
new file mode 100644
index 000000000..cc1046869
--- /dev/null
+++ b/rust/tests/tests/test_rc_arc.rs
@@ -0,0 +1,366 @@
+// 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.
+
+//! Tests for Rc and Arc serialization support in Fury
+
+use fory_core::fory::Fory;
+use std::collections::HashMap;
+use std::rc::Rc;
+use std::sync::Arc;
+
+#[test]
+fn test_rc_string_serialization() {
+    let fury = Fory::default();
+
+    let data = String::from("Hello, Rc!");
+    let rc_data = Rc::new(data);
+
+    let serialized = fury.serialize(&rc_data);
+    let deserialized: Rc<String> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(*rc_data, *deserialized);
+    assert_eq!("Hello, Rc!", *deserialized);
+}
+
+#[test]
+fn test_arc_string_serialization() {
+    let fury = Fory::default();
+
+    let data = String::from("Hello, Arc!");
+    let arc_data = Arc::new(data);
+
+    let serialized = fury.serialize(&arc_data);
+    let deserialized: Arc<String> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(*arc_data, *deserialized);
+    assert_eq!("Hello, Arc!", *deserialized);
+}
+
+#[test]
+fn test_rc_number_serialization() {
+    let fury = Fory::default();
+
+    let rc_number = Rc::new(42i32);
+
+    let serialized = fury.serialize(&rc_number);
+    let deserialized: Rc<i32> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(*rc_number, *deserialized);
+    assert_eq!(42, *deserialized);
+}
+
+#[test]
+fn test_arc_number_serialization() {
+    let fury = Fory::default();
+
+    let arc_number = Arc::new(100i64);
+
+    let serialized = fury.serialize(&arc_number);
+    let deserialized: Arc<i64> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(*arc_number, *deserialized);
+    assert_eq!(100, *deserialized);
+}
+
+#[test]
+fn test_rc_in_collections() {
+    let fury = Fory::default();
+
+    let string1 = Rc::new(String::from("First"));
+    let string2 = Rc::new(String::from("Second"));
+
+    let strings = vec![string1.clone(), string2.clone(), string1.clone()];
+
+    let serialized = fury.serialize(&strings);
+    let deserialized: Vec<Rc<String>> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(strings.len(), deserialized.len());
+    assert_eq!(*strings[0], *deserialized[0]);
+    assert_eq!(*strings[1], *deserialized[1]);
+    assert_eq!(*strings[2], *deserialized[2]);
+    assert_eq!("First", *deserialized[0]);
+    assert_eq!("Second", *deserialized[1]);
+    assert_eq!("First", *deserialized[2]);
+}
+
+#[test]
+fn test_arc_in_collections() {
+    let fury = Fory::default();
+
+    let number1 = Arc::new(123i32);
+    let number2 = Arc::new(456i32);
+
+    let numbers = vec![number1.clone(), number2.clone(), number1.clone()];
+
+    let serialized = fury.serialize(&numbers);
+    let deserialized: Vec<Arc<i32>> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(numbers.len(), deserialized.len());
+    assert_eq!(*numbers[0], *deserialized[0]);
+    assert_eq!(*numbers[1], *deserialized[1]);
+    assert_eq!(*numbers[2], *deserialized[2]);
+    assert_eq!(123, *deserialized[0]);
+    assert_eq!(456, *deserialized[1]);
+    assert_eq!(123, *deserialized[2]);
+}
+
+#[test]
+fn test_rc_vec_serialization() {
+    let fury = Fory::default();
+
+    let data = vec![1, 2, 3, 4, 5];
+    let rc_data = Rc::new(data);
+
+    let serialized = fury.serialize(&rc_data);
+    let deserialized: Rc<Vec<i32>> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(*rc_data, *deserialized);
+    assert_eq!(vec![1, 2, 3, 4, 5], *deserialized);
+}
+
+#[test]
+fn test_arc_vec_serialization() {
+    let fury = Fory::default();
+
+    let data = vec![String::from("a"), String::from("b"), String::from("c")];
+    let arc_data = Arc::new(data);
+
+    let serialized = fury.serialize(&arc_data);
+    let deserialized: Arc<Vec<String>> = 
fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(*arc_data, *deserialized);
+    assert_eq!(vec!["a", "b", "c"], *deserialized);
+}
+
+#[test]
+fn test_mixed_rc_arc_serialization() {
+    let fury = Fory::default();
+
+    // Test basic types wrapped in Rc/Arc
+    let rc_number = Rc::new(42i32);
+    let arc_number = Arc::new(100i64);
+
+    let rc_serialized = fury.serialize(&rc_number);
+    let arc_serialized = fury.serialize(&arc_number);
+
+    let rc_deserialized: Rc<i32> = fury.deserialize(&rc_serialized).unwrap();
+    let arc_deserialized: Arc<i64> = 
fury.deserialize(&arc_serialized).unwrap();
+
+    assert_eq!(*rc_number, *rc_deserialized);
+    assert_eq!(*arc_number, *arc_deserialized);
+}
+
+#[test]
+fn test_nested_rc_arc() {
+    let fury = Fory::default();
+
+    // Test Rc containing Arc
+    let inner_data = Arc::new(String::from("nested"));
+    let outer_data = Rc::new(inner_data.clone());
+
+    let serialized = fury.serialize(&outer_data);
+    let deserialized: Rc<Arc<String>> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(**outer_data, **deserialized);
+}
+
+#[test]
+fn test_rc_arc_with_hashmaps() {
+    let fury = Fory::default();
+
+    let string_data = Arc::new(String::from("shared"));
+
+    let mut map = HashMap::new();
+    map.insert("key1".to_string(), string_data.clone());
+    map.insert("key2".to_string(), string_data.clone());
+
+    let serialized = fury.serialize(&map);
+    let deserialized: HashMap<String, Arc<String>> = 
fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(map.len(), deserialized.len());
+    assert_eq!(*map["key1"], *deserialized["key1"]);
+    assert_eq!(*map["key2"], *deserialized["key2"]);
+    assert_eq!("shared", *deserialized["key1"]);
+    assert_eq!("shared", *deserialized["key2"]);
+}
+
+// Additional tests moved from arc.rs and rc.rs serializer modules
+
+#[test]
+fn test_arc_serialization_basic() {
+    let fury = Fory::default();
+    let arc = Arc::new(42i32);
+
+    let serialized = fury.serialize(&arc);
+    let deserialized: Arc<i32> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(*deserialized, 42);
+}
+
+#[test]
+fn test_arc_shared_reference() {
+    let fury = Fory::default();
+    let arc1 = Arc::new(String::from("shared"));
+
+    let serialized = fury.serialize(&arc1);
+    let deserialized: Arc<String> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(*deserialized, "shared");
+}
+
+#[test]
+fn test_arc_shared_reference_in_vec() {
+    let fury = Fory::default();
+
+    let shared = Arc::new(String::from("shared_value"));
+    let vec = vec![shared.clone(), shared.clone(), shared.clone()];
+
+    let serialized = fury.serialize(&vec);
+    let deserialized: Vec<Arc<String>> = 
fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(deserialized.len(), 3);
+    assert_eq!(*deserialized[0], "shared_value");
+    assert_eq!(*deserialized[1], "shared_value");
+    assert_eq!(*deserialized[2], "shared_value");
+
+    assert!(Arc::ptr_eq(&deserialized[0], &deserialized[1]));
+    assert!(Arc::ptr_eq(&deserialized[1], &deserialized[2]));
+    assert!(Arc::ptr_eq(&deserialized[0], &deserialized[2]));
+}
+
+#[test]
+fn test_arc_multiple_shared_references() {
+    let fury = Fory::default();
+
+    let shared1 = Arc::new(42i32);
+    let shared2 = Arc::new(100i32);
+
+    let vec = vec![
+        shared1.clone(),
+        shared2.clone(),
+        shared1.clone(),
+        shared2.clone(),
+        shared1.clone(),
+    ];
+
+    let serialized = fury.serialize(&vec);
+    let deserialized: Vec<Arc<i32>> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(deserialized.len(), 5);
+    assert_eq!(*deserialized[0], 42);
+    assert_eq!(*deserialized[1], 100);
+    assert_eq!(*deserialized[2], 42);
+    assert_eq!(*deserialized[3], 100);
+    assert_eq!(*deserialized[4], 42);
+
+    assert!(Arc::ptr_eq(&deserialized[0], &deserialized[2]));
+    assert!(Arc::ptr_eq(&deserialized[0], &deserialized[4]));
+    assert!(Arc::ptr_eq(&deserialized[1], &deserialized[3]));
+    assert!(!Arc::ptr_eq(&deserialized[0], &deserialized[1]));
+}
+
+#[test]
+fn test_arc_thread_safety() {
+    use std::thread;
+
+    let fury = Fory::default();
+    let arc = Arc::new(vec![1, 2, 3, 4, 5]);
+
+    let serialized = fury.serialize(&arc);
+
+    // Test that Arc can be sent across threads
+    let handle = thread::spawn(move || {
+        let fury = Fory::default();
+        let deserialized: Arc<Vec<i32>> = 
fury.deserialize(&serialized).unwrap();
+        assert_eq!(*deserialized, vec![1, 2, 3, 4, 5]);
+    });
+
+    handle.join().unwrap();
+}
+
+#[test]
+fn test_rc_serialization_basic() {
+    let fury = Fory::default();
+    let rc = Rc::new(42i32);
+
+    let serialized = fury.serialize(&rc);
+    let deserialized: Rc<i32> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(*deserialized, 42);
+}
+
+#[test]
+fn test_rc_shared_reference() {
+    let fury = Fory::default();
+    let rc1 = Rc::new(String::from("shared"));
+
+    let serialized = fury.serialize(&rc1);
+    let deserialized: Rc<String> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(*deserialized, "shared");
+}
+
+#[test]
+fn test_rc_shared_reference_in_vec() {
+    let fury = Fory::default();
+
+    let shared = Rc::new(String::from("shared_value"));
+    let vec = vec![shared.clone(), shared.clone(), shared.clone()];
+
+    let serialized = fury.serialize(&vec);
+    let deserialized: Vec<Rc<String>> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(deserialized.len(), 3);
+    assert_eq!(*deserialized[0], "shared_value");
+    assert_eq!(*deserialized[1], "shared_value");
+    assert_eq!(*deserialized[2], "shared_value");
+
+    assert!(Rc::ptr_eq(&deserialized[0], &deserialized[1]));
+    assert!(Rc::ptr_eq(&deserialized[1], &deserialized[2]));
+    assert!(Rc::ptr_eq(&deserialized[0], &deserialized[2]));
+}
+
+#[test]
+fn test_rc_multiple_shared_references() {
+    let fury = Fory::default();
+
+    let shared1 = Rc::new(42i32);
+    let shared2 = Rc::new(100i32);
+
+    let vec = vec![
+        shared1.clone(),
+        shared2.clone(),
+        shared1.clone(),
+        shared2.clone(),
+        shared1.clone(),
+    ];
+
+    let serialized = fury.serialize(&vec);
+    let deserialized: Vec<Rc<i32>> = fury.deserialize(&serialized).unwrap();
+
+    assert_eq!(deserialized.len(), 5);
+    assert_eq!(*deserialized[0], 42);
+    assert_eq!(*deserialized[1], 100);
+    assert_eq!(*deserialized[2], 42);
+    assert_eq!(*deserialized[3], 100);
+    assert_eq!(*deserialized[4], 42);
+
+    assert!(Rc::ptr_eq(&deserialized[0], &deserialized[2]));
+    assert!(Rc::ptr_eq(&deserialized[0], &deserialized[4]));
+    assert!(Rc::ptr_eq(&deserialized[1], &deserialized[3]));
+    assert!(!Rc::ptr_eq(&deserialized[0], &deserialized[1]));
+}
diff --git a/rust/tests/tests/test_ref_resolver.rs 
b/rust/tests/tests/test_ref_resolver.rs
new file mode 100644
index 000000000..ebaaf8002
--- /dev/null
+++ b/rust/tests/tests/test_ref_resolver.rs
@@ -0,0 +1,129 @@
+// 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.
+
+//! Tests for RefWriter and RefReader functionality
+
+use fory_core::buffer::Writer;
+use fory_core::resolver::ref_resolver::{RefReader, RefWriter};
+use std::rc::Rc;
+use std::sync::Arc;
+
+#[test]
+fn test_rc_ref_tracking() {
+    let mut ref_writer = RefWriter::new();
+    let mut writer = Writer::default();
+
+    let rc1 = Rc::new(42i32);
+    let rc2 = rc1.clone();
+
+    // First write should register the reference
+    assert!(!ref_writer.try_write_rc_ref(&mut writer, &rc1));
+
+    // Second write should find existing reference
+    assert!(ref_writer.try_write_rc_ref(&mut writer, &rc2));
+}
+
+#[test]
+fn test_arc_ref_tracking() {
+    let mut ref_writer = RefWriter::new();
+    let mut writer = Writer::default();
+
+    let arc1 = Arc::new(42i32);
+    let arc2 = arc1.clone();
+
+    // First write should register the reference
+    assert!(!ref_writer.try_write_arc_ref(&mut writer, &arc1));
+
+    // Second write should find existing reference
+    assert!(ref_writer.try_write_arc_ref(&mut writer, &arc2));
+}
+
+#[test]
+fn test_rc_storage_and_retrieval() {
+    let mut ref_reader = RefReader::new();
+    let rc = Rc::new(String::from("test"));
+
+    let ref_id = ref_reader.store_rc_ref(rc.clone());
+
+    let retrieved = ref_reader.get_rc_ref::<String>(ref_id).unwrap();
+    assert_eq!(*retrieved, "test");
+    assert!(Rc::ptr_eq(&rc, &retrieved));
+}
+
+#[test]
+fn test_arc_storage_and_retrieval() {
+    let mut ref_reader = RefReader::new();
+    let arc = Arc::new(String::from("test"));
+
+    let ref_id = ref_reader.store_arc_ref(arc.clone());
+
+    let retrieved = ref_reader.get_arc_ref::<String>(ref_id).unwrap();
+    assert_eq!(*retrieved, "test");
+    assert!(Arc::ptr_eq(&arc, &retrieved));
+}
+
+#[test]
+fn test_ref_writer_clear() {
+    let mut ref_writer = RefWriter::new();
+    let mut writer = Writer::default();
+
+    let rc = Rc::new(42i32);
+
+    // Register a reference
+    assert!(!ref_writer.try_write_rc_ref(&mut writer, &rc));
+
+    // Clear the writer
+    ref_writer.clear();
+
+    // After clearing, should register as new reference again
+    assert!(!ref_writer.try_write_rc_ref(&mut writer, &rc));
+}
+
+#[test]
+fn test_ref_reader_clear() {
+    let mut ref_reader = RefReader::new();
+    let rc = Rc::new(String::from("test"));
+
+    // Store a reference
+    let ref_id = ref_reader.store_rc_ref(rc.clone());
+    assert!(ref_reader.get_rc_ref::<String>(ref_id).is_some());
+
+    // Clear the reader
+    ref_reader.clear();
+
+    // After clearing, reference should no longer be found
+    assert!(ref_reader.get_rc_ref::<String>(ref_id).is_none());
+}
+
+#[test]
+fn test_ref_writer_ref_reader_separation() {
+    let mut ref_writer = RefWriter::new();
+    let mut ref_reader = RefReader::new();
+    let mut writer = Writer::default();
+
+    let rc1 = Rc::new(42i32);
+    let rc2 = rc1.clone();
+
+    // Test writing with RefWriter
+    assert!(!ref_writer.try_write_rc_ref(&mut writer, &rc1));
+    assert!(ref_writer.try_write_rc_ref(&mut writer, &rc2));
+
+    // Test storing and retrieving with RefReader
+    let ref_id = ref_reader.store_rc_ref(rc1.clone());
+    let retrieved = ref_reader.get_rc_ref::<i32>(ref_id).unwrap();
+    assert!(Rc::ptr_eq(&rc1, &retrieved));
+}


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


Reply via email to