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

Kriskras99 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/avro-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new 7349015  fix: Enable `#[serde(remote = "..")]` support (#564)
7349015 is described below

commit 7349015a402a502c9cfa2d323c2273bbd3680ab1
Author: Kriskras99 <[email protected]>
AuthorDate: Tue Jun 23 21:04:38 2026 +0200

    fix: Enable `#[serde(remote = "..")]` support (#564)
    
    * fix: Enable `#[serde(remote = "..")]` support
    
    * fix: Improve documentation and fix test name
---
 avro/src/serde/derive.rs                       |  3 --
 avro_derive/src/attributes/mod.rs              | 14 ------
 avro_derive/src/attributes/serde.rs            | 11 +++--
 avro_derive/tests/serde.rs                     | 68 ++++++++++++++++++++++++++
 avro_derive/tests/ui/avro_rs_373_remote.rs     | 33 -------------
 avro_derive/tests/ui/avro_rs_373_remote.stderr |  9 ----
 6 files changed, 76 insertions(+), 62 deletions(-)

diff --git a/avro/src/serde/derive.rs b/avro/src/serde/derive.rs
index 38f17bf..6d66fce 100644
--- a/avro/src/serde/derive.rs
+++ b/avro/src/serde/derive.rs
@@ -175,13 +175,10 @@ use crate::{
 ///     - `untagged`
 ///     - `variant_identifier`
 ///     - `field_identifier`
-///     - `remote`
 ///     - `rename_all(serialize = "..", deserialize = "..")` where `serialize` 
!= `deserialize`
 /// - Variant attributes
 ///     - `other`
 ///     - `untagged`
-/// - Field attributes
-///     - `getter`
 ///
 /// ## Working with foreign types
 ///
diff --git a/avro_derive/src/attributes/mod.rs 
b/avro_derive/src/attributes/mod.rs
index ebb2997..e68bbbb 100644
--- a/avro_derive/src/attributes/mod.rs
+++ b/avro_derive/src/attributes/mod.rs
@@ -63,12 +63,6 @@ impl NamedTypeOptions {
                 "AvroSchema derive does not support changing the tagging Serde 
generates (`tag`, `content`, `untagged`, `variant_identifier`, 
`field_identifier`)",
             ));
         }
-        if serde.remote.is_some() {
-            errors.push(syn::Error::new(
-                span,
-                "AvroSchema derive does not support the Serde `remote` 
attribute",
-            ));
-        }
         if serde.rename_all.deserialize != serde.rename_all.serialize {
             errors.push(syn::Error::new(
                 span,
@@ -284,14 +278,6 @@ impl FieldOptions {
         // Collect errors so user gets all feedback at once
         let mut errors = Vec::new();
 
-        // Check for any Serde attributes that are hard errors
-        if serde.getter.is_some() {
-            errors.push(syn::Error::new(
-                span,
-                "AvroSchema derive does not support the Serde `getter` 
attribute",
-            ));
-        }
-
         // Check for conflicts between Serde and Avro
         if avro.skip && !(serde.skip || (serde.skip_serializing && 
serde.skip_deserializing)) {
             errors.push(syn::Error::new(
diff --git a/avro_derive/src/attributes/serde.rs 
b/avro_derive/src/attributes/serde.rs
index b1ca6fa..6149752 100644
--- a/avro_derive/src/attributes/serde.rs
+++ b/avro_derive/src/attributes/serde.rs
@@ -117,8 +117,12 @@ pub struct ContainerAttributes {
     pub _default: Option<SerdeDefault>,
     /// This type is the serde implementation for a "remote" type.
     ///
-    /// This makes the (de)serialisation use/return a different type.
-    pub remote: Option<String>,
+    /// This allows the user to derive `Serialize`/`Deserialize` for a type in 
another crate.
+    ///
+    /// This makes the (de)serialisation use/return a different type. To make 
this work Serde requires
+    /// that the remote type and this type have the same fields so the schema 
generated is correct.
+    #[darling(rename = "remote")]
+    pub _remote: Option<String>,
     /// Directly use the inner type for (de)serialisation.
     #[darling(default)]
     pub transparent: bool,
@@ -243,7 +247,8 @@ pub struct FieldAttributes {
     #[darling(rename = "borrow")]
     pub _borrow: Option<SerdeBorrow>,
     /// Used for remote types.
-    pub getter: Option<String>,
+    #[darling(rename = "getter")]
+    pub _getter: Option<String>,
 }
 
 #[cfg(test)]
diff --git a/avro_derive/tests/serde.rs b/avro_derive/tests/serde.rs
index 128fede..0f03713 100644
--- a/avro_derive/tests/serde.rs
+++ b/avro_derive/tests/serde.rs
@@ -370,6 +370,74 @@ mod container_attributes {
             a: vec!["spam".to_string()],
         });
     }
+
+    #[test]
+    fn avro_rs_564_remote() {
+        // The types and supporting code here have been pulled directly from 
the Serde documentation
+        // (https://serde.rs/remote-derive.html)
+
+        // Pretend that this is somebody else's crate, not a module.
+        mod other_crate {
+            // Neither Serde nor the other crate provides Serialize and 
Deserialize
+            // impls for this struct. Oh, and the fields are private.
+            #[derive(Debug, PartialEq, Eq)]
+            pub struct Duration {
+                secs: i64,
+                nanos: i32,
+            }
+
+            impl Duration {
+                pub fn new(secs: i64, nanos: i32) -> Self {
+                    Duration { secs, nanos }
+                }
+
+                pub fn seconds(&self) -> i64 {
+                    self.secs
+                }
+
+                pub fn subsec_nanos(&self) -> i32 {
+                    self.nanos
+                }
+            }
+        }
+
+        
////////////////////////////////////////////////////////////////////////////////
+
+        use other_crate::Duration;
+        use serde::{Deserialize, Serialize};
+
+        // Provide getters for every private field of the remote struct. The 
getter must
+        // return either `T` or `&T` where `T` is the type of the field.
+        #[derive(Serialize, Deserialize, AvroSchema)]
+        #[serde(remote = "Duration")]
+        struct DurationDef {
+            #[serde(getter = "Duration::seconds")]
+            secs: i64,
+            #[serde(getter = "Duration::subsec_nanos")]
+            nanos: i32,
+        }
+
+        // Provide a conversion to construct the remote type.
+        impl From<DurationDef> for Duration {
+            fn from(def: DurationDef) -> Duration {
+                Duration::new(def.secs, def.nanos)
+            }
+        }
+
+        #[derive(Serialize, Deserialize, AvroSchema, Debug, PartialEq, Eq)]
+        struct Process {
+            command_line: String,
+
+            #[serde(with = "DurationDef")]
+            #[avro(with)]
+            wall_time: Duration,
+        }
+
+        serde_assert(Process {
+            command_line: "abracadabra".to_string(),
+            wall_time: Duration::new(15, 42),
+        });
+    }
 }
 
 mod variant_attributes {
diff --git a/avro_derive/tests/ui/avro_rs_373_remote.rs 
b/avro_derive/tests/ui/avro_rs_373_remote.rs
deleted file mode 100644
index b6029c8..0000000
--- a/avro_derive/tests/ui/avro_rs_373_remote.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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 apache_avro::AvroSchema;
-
-#[derive(AvroSchema)]
-struct Foo {
-    a: String,
-    b: i32,
-}
-
-#[derive(AvroSchema)]
-#[serde(remote = "Foo")]
-struct FooRemote {
-    a: String,
-    b: i32,
-}
-
-pub fn main() {}
diff --git a/avro_derive/tests/ui/avro_rs_373_remote.stderr 
b/avro_derive/tests/ui/avro_rs_373_remote.stderr
deleted file mode 100644
index fe4fd10..0000000
--- a/avro_derive/tests/ui/avro_rs_373_remote.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error: AvroSchema derive does not support the Serde `remote` attribute
-  --> tests/ui/avro_rs_373_remote.rs:27:1
-   |
-27 | / #[serde(remote = "Foo")]
-28 | | struct FooRemote {
-29 | |     a: String,
-30 | |     b: i32,
-31 | | }
-   | |_^

Reply via email to