This is an automated email from the ASF dual-hosted git repository.

mgrigorov pushed a commit to branch raii-for-thread-locals
in repository https://gitbox.apache.org/repos/asf/avro-rs.git

commit 81309b3984fec4c372cb850bea803656398a0c9d
Author: Martin Tzvetanov Grigorov <[email protected]>
AuthorDate: Fri Jan 23 23:13:41 2026 +0200

    Use RAII for setting the thread locals
    
    This way if the (de)serialization fails the previous value will be
    restored.
    
    Fix a rustdoc link for slice_opt
    
    Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
---
 avro/src/serde/with.rs | 62 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 41 insertions(+), 21 deletions(-)

diff --git a/avro/src/serde/with.rs b/avro/src/serde/with.rs
index 5162bc5..a7649fd 100644
--- a/avro/src/serde/with.rs
+++ b/avro/src/serde/with.rs
@@ -37,6 +37,36 @@ pub(crate) enum BytesType {
     Fixed,
 }
 
+struct BytesTypeGuard(BytesType);
+impl BytesTypeGuard {
+    fn set(temp: BytesType) -> Self {
+        let prev = SER_BYTES_TYPE.get();
+        SER_BYTES_TYPE.set(temp);
+        Self(prev)
+    }
+}
+
+impl Drop for BytesTypeGuard {
+    fn drop(&mut self) {
+        SER_BYTES_TYPE.set(self.0);
+    }
+}
+
+struct BorrowedGuard(bool);
+impl BorrowedGuard {
+    fn set(temp: bool) -> Self {
+        let prev = DE_BYTES_BORROWED.get();
+        DE_BYTES_BORROWED.set(temp);
+        Self(prev)
+    }
+}
+
+impl Drop for BorrowedGuard {
+    fn drop(&mut self) {
+        DE_BYTES_BORROWED.set(self.0);
+    }
+}
+
 /// Efficient (de)serialization of Avro bytes values.
 ///
 /// This module is intended to be used through the Serde `with` attribute.
@@ -167,7 +197,7 @@ pub mod bytes_opt {
 ///
 /// [`apache_avro::serde::fixed_opt`]: fixed_opt
 pub mod fixed {
-    use super::{BytesType, SER_BYTES_TYPE};
+    use super::BytesType;
     use serde::{Deserializer, Serializer};
 
     use crate::{
@@ -197,10 +227,8 @@ pub mod fixed {
     where
         S: Serializer,
     {
-        SER_BYTES_TYPE.set(BytesType::Fixed);
-        let res = serde_bytes::serialize(bytes, serializer);
-        SER_BYTES_TYPE.set(BytesType::Bytes);
-        res
+        let _guard = crate::serde::with::BytesTypeGuard::set(BytesType::Fixed);
+        serde_bytes::serialize(bytes, serializer)
     }
 
     pub fn deserialize<'de, D, const N: usize>(deserializer: D) -> Result<[u8; 
N], D::Error>
@@ -235,7 +263,7 @@ pub mod fixed {
 ///
 /// [`apache_avro::serde::fixed`]: fixed
 pub mod fixed_opt {
-    use super::{BytesType, SER_BYTES_TYPE};
+    use super::BytesType;
     use serde::{Deserializer, Serializer};
     use std::borrow::Borrow;
 
@@ -263,10 +291,8 @@ pub mod fixed_opt {
         S: Serializer,
         B: Borrow<[u8]> + serde_bytes::Serialize,
     {
-        SER_BYTES_TYPE.set(BytesType::Fixed);
-        let res = serde_bytes::serialize(bytes, serializer);
-        SER_BYTES_TYPE.set(BytesType::Bytes);
-        res
+        let _guard = crate::serde::with::BytesTypeGuard::set(BytesType::Fixed);
+        serde_bytes::serialize(bytes, serializer)
     }
 
     pub fn deserialize<'de, D, const N: usize>(deserializer: D) -> 
Result<Option<[u8; N]>, D::Error>
@@ -301,9 +327,8 @@ pub mod fixed_opt {
 ///
 /// [`Value::Bytes`]: crate::types::Value::Bytes
 /// [`Value::Fixed`]: crate::types::Value::Fixed
-/// [`apache_avro::serde::slice`]: slice_opt
+/// [`apache_avro::serde::slice_opt`]: slice_opt
 pub mod slice {
-    use super::DE_BYTES_BORROWED;
     use serde::{Deserializer, Serializer};
 
     use crate::{
@@ -327,10 +352,8 @@ pub mod slice {
     where
         D: Deserializer<'de>,
     {
-        DE_BYTES_BORROWED.set(true);
-        let res = serde_bytes::deserialize(deserializer);
-        DE_BYTES_BORROWED.set(false);
-        res
+        let _guard = crate::serde::with::BorrowedGuard::set(true);
+        serde_bytes::deserialize(deserializer)
     }
 }
 
@@ -360,7 +383,6 @@ pub mod slice {
 /// [`Value::Fixed`]: crate::types::Value::Fixed
 /// [`apache_avro::serde::slice`]: mod@slice
 pub mod slice_opt {
-    use super::DE_BYTES_BORROWED;
     use serde::{Deserializer, Serializer};
     use std::borrow::Borrow;
 
@@ -388,10 +410,8 @@ pub mod slice_opt {
     where
         D: Deserializer<'de>,
     {
-        DE_BYTES_BORROWED.set(true);
-        let res = serde_bytes::deserialize(deserializer);
-        DE_BYTES_BORROWED.set(false);
-        res
+        let _guard = crate::serde::with::BorrowedGuard::set(true);
+        serde_bytes::deserialize(deserializer)
     }
 }
 

Reply via email to