You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by mg...@apache.org on 2022/03/21 10:42:39 UTC

[avro] 01/01: AVRO-3452: Implement custom deserialization for Name that employs the special parsing of name and namespace

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

mgrigorov pushed a commit to branch avro-3452-manual-deseriaze-for-Name
in repository https://gitbox.apache.org/repos/asf/avro.git

commit 314e7d3dd27f5fe2f54816e0d4d72f5c26b0b139
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
AuthorDate: Mon Mar 21 12:41:37 2022 +0200

    AVRO-3452: Implement custom deserialization for Name that employs the special parsing of name and namespace
    
    Signed-off-by: Martin Tzvetanov Grigorov <mg...@apache.org>
---
 lang/rust/avro/src/schema.rs   | 23 +++++++++++++++++++++--
 lang/rust/avro/tests/schema.rs |  2 ++
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/lang/rust/avro/src/schema.rs b/lang/rust/avro/src/schema.rs
index 9c0750b..6f3e38b 100644
--- a/lang/rust/avro/src/schema.rs
+++ b/lang/rust/avro/src/schema.rs
@@ -228,7 +228,7 @@ impl From<&types::Value> for SchemaKind {
 ///
 /// More information about schema names can be found in the
 /// [Avro specification](https://avro.apache.org/docs/current/spec.html#names)
-#[derive(Clone, Debug, Deserialize, Hash, PartialEq, Eq)]
+#[derive(Clone, Debug, Hash, PartialEq, Eq)]
 pub struct Name {
     pub name: String,
     pub namespace: Namespace,
@@ -265,7 +265,7 @@ impl Name {
     }
 
     /// Parse a `serde_json::Value` into a `Name`.
-    fn parse(complex: &Map<String, Value>) -> AvroResult<Self> {
+    pub(crate) fn parse(complex: &Map<String, Value>) -> AvroResult<Self> {
         let (name, namespace_from_name) = complex
             .name()
             .map(|name| Name::get_name_and_namespace(name.as_str()).unwrap())
@@ -335,6 +335,25 @@ impl fmt::Display for Name {
     }
 }
 
+impl<'de> Deserialize<'de> for Name {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: serde::de::Deserializer<'de>,
+    {
+        serde_json::Value::deserialize(deserializer).and_then(|value| {
+            if let Value::Object(json) = value {
+                Name::parse(&json).map_err(serde::de::Error::custom)
+            } else {
+                use serde::de::Error;
+                Err(D::Error::custom(format!(
+                    "Expected a json object: {:?}",
+                    value
+                )))
+            }
+        })
+    }
+}
+
 pub(crate) struct ResolvedSchema<'s> {
     names_ref: NamesRef<'s>,
     root_schema: &'s Schema,
diff --git a/lang/rust/avro/tests/schema.rs b/lang/rust/avro/tests/schema.rs
index c404452..72c7e1d 100644
--- a/lang/rust/avro/tests/schema.rs
+++ b/lang/rust/avro/tests/schema.rs
@@ -1080,6 +1080,8 @@ fn test_fullname_fullname_and_namespace_specified() {
     let name: Name =
         serde_json::from_str(r#"{"name": "a.b.c.d", "namespace": "o.a.h", "aliases": null}"#)
             .unwrap();
+    assert_eq!(&name.name, "d");
+    assert_eq!(name.namespace, Some("a.b.c".to_owned()));
     let fullname = name.fullname(None);
     assert_eq!("a.b.c.d", fullname);
 }