[ 
https://issues.apache.org/jira/browse/AVRO-3507?focusedWorklogId=767711&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-767711
 ]

ASF GitHub Bot logged work on AVRO-3507:
----------------------------------------

                Author: ASF GitHub Bot
            Created on: 08/May/22 19:45
            Start Date: 08/May/22 19:45
    Worklog Time Spent: 10m 
      Work Description: martin-g commented on code in PR #1681:
URL: https://github.com/apache/avro/pull/1681#discussion_r867534037


##########
lang/rust/avro/src/reader.rs:
##########
@@ -569,4 +663,158 @@ mod tests {
         let reader = Reader::new(&result[..]).unwrap();
         assert_eq!(reader.user_metadata(), &user_meta_data);
     }
+
+    #[derive(Deserialize, Clone, PartialEq, Debug)]
+    struct TestSingleObjectReader {
+        a: i64,
+        b: f64,
+        c: Vec<String>,
+    }
+
+    impl AvroSchema for TestSingleObjectReader {
+        fn get_schema() -> Schema {
+            let schema = r#"
+            {
+                "type":"record",
+                "name":"TestSingleObjectWrtierSerialize",
+                "fields":[
+                    {
+                        "name":"a",
+                        "type":"long"
+                    },
+                    {
+                        "name":"b",
+                        "type":"double"
+                    },
+                    {
+                        "name":"c",
+                        "type":{
+                            "type":"array",
+                            "items":"string"
+                        }
+                    }
+                ]
+            }
+            "#;
+            Schema::parse_str(schema).unwrap()
+        }
+    }
+
+    impl From<Value> for TestSingleObjectReader {
+        fn from(obj: Value) -> TestSingleObjectReader {
+            if let Value::Record(fields) = obj {
+                let mut a = None;
+                let mut b = None;
+                let mut c = vec![];
+                for (field_name, v) in fields {
+                    match (field_name.as_str(), v) {
+                        ("a", Value::Long(i)) => a = Some(i),
+                        ("b", Value::Double(d)) => b = Some(d),
+                        ("c", Value::Array(v)) => {
+                            for inner_val in v {
+                                if let Value::String(s) = inner_val {
+                                    c.push(s);
+                                }
+                            }
+                        }
+                        _ => panic!("Unexpected pair"),

Review Comment:
   ```suggestion
                           (key, value) => panic!("Unexpected pair: {:?} -> 
{:?}", key, value),
   ```



##########
lang/rust/avro/examples/test_interop_single_object_encoding.rs:
##########
@@ -58,3 +63,15 @@ fn main() {
         .expect("Should encode");
     assert_eq!(file_message, generated_encoding)
 }
+
+fn test_read() {
+    let file_message = std::fs::read(format!("{}/test_message.bin", 
RESOURCES_FOLDER))

Review Comment:
   Is this `read` really needed ?



##########
lang/rust/avro/src/reader.rs:
##########
@@ -569,4 +663,158 @@ mod tests {
         let reader = Reader::new(&result[..]).unwrap();
         assert_eq!(reader.user_metadata(), &user_meta_data);
     }
+
+    #[derive(Deserialize, Clone, PartialEq, Debug)]
+    struct TestSingleObjectReader {
+        a: i64,
+        b: f64,
+        c: Vec<String>,
+    }
+
+    impl AvroSchema for TestSingleObjectReader {
+        fn get_schema() -> Schema {
+            let schema = r#"
+            {
+                "type":"record",
+                "name":"TestSingleObjectWrtierSerialize",
+                "fields":[
+                    {
+                        "name":"a",
+                        "type":"long"
+                    },
+                    {
+                        "name":"b",
+                        "type":"double"
+                    },
+                    {
+                        "name":"c",
+                        "type":{
+                            "type":"array",
+                            "items":"string"
+                        }
+                    }
+                ]
+            }
+            "#;
+            Schema::parse_str(schema).unwrap()
+        }
+    }
+
+    impl From<Value> for TestSingleObjectReader {
+        fn from(obj: Value) -> TestSingleObjectReader {
+            if let Value::Record(fields) = obj {
+                let mut a = None;
+                let mut b = None;
+                let mut c = vec![];
+                for (field_name, v) in fields {
+                    match (field_name.as_str(), v) {
+                        ("a", Value::Long(i)) => a = Some(i),
+                        ("b", Value::Double(d)) => b = Some(d),
+                        ("c", Value::Array(v)) => {
+                            for inner_val in v {
+                                if let Value::String(s) = inner_val {
+                                    c.push(s);
+                                }
+                            }
+                        }
+                        _ => panic!("Unexpected pair"),
+                    }
+                }
+                TestSingleObjectReader {
+                    a: a.unwrap(),
+                    b: b.unwrap(),
+                    c,
+                }
+            } else {
+                panic!("Should be record value")

Review Comment:
   ```suggestion
                   panic!("Should be record value: {:?}", obj)
   ```



##########
lang/rust/avro/src/reader.rs:
##########
@@ -569,4 +663,158 @@ mod tests {
         let reader = Reader::new(&result[..]).unwrap();
         assert_eq!(reader.user_metadata(), &user_meta_data);
     }
+
+    #[derive(Deserialize, Clone, PartialEq, Debug)]
+    struct TestSingleObjectReader {
+        a: i64,
+        b: f64,
+        c: Vec<String>,
+    }
+
+    impl AvroSchema for TestSingleObjectReader {
+        fn get_schema() -> Schema {
+            let schema = r#"
+            {
+                "type":"record",
+                "name":"TestSingleObjectWrtierSerialize",
+                "fields":[
+                    {
+                        "name":"a",
+                        "type":"long"
+                    },
+                    {
+                        "name":"b",
+                        "type":"double"
+                    },
+                    {
+                        "name":"c",
+                        "type":{
+                            "type":"array",
+                            "items":"string"
+                        }
+                    }
+                ]
+            }
+            "#;
+            Schema::parse_str(schema).unwrap()
+        }
+    }
+
+    impl From<Value> for TestSingleObjectReader {
+        fn from(obj: Value) -> TestSingleObjectReader {
+            if let Value::Record(fields) = obj {
+                let mut a = None;
+                let mut b = None;
+                let mut c = vec![];
+                for (field_name, v) in fields {
+                    match (field_name.as_str(), v) {
+                        ("a", Value::Long(i)) => a = Some(i),
+                        ("b", Value::Double(d)) => b = Some(d),
+                        ("c", Value::Array(v)) => {
+                            for inner_val in v {
+                                if let Value::String(s) = inner_val {
+                                    c.push(s);
+                                }
+                            }
+                        }
+                        _ => panic!("Unexpected pair"),
+                    }
+                }
+                TestSingleObjectReader {
+                    a: a.unwrap(),
+                    b: b.unwrap(),
+                    c,
+                }
+            } else {
+                panic!("Should be record value")
+            }
+        }
+    }
+
+    impl From<TestSingleObjectReader> for Value {
+        fn from(obj: TestSingleObjectReader) -> Value {
+            Value::Record(vec![
+                ("a".into(), obj.a.into()),
+                ("b".into(), obj.b.into()),
+                (
+                    "c".into(),
+                    Value::Array(obj.c.into_iter().map(|s| 
s.into()).collect()),
+                ),
+            ])
+        }
+    }
+
+    #[test]
+    fn test_single_object_reader() {
+        let obj = TestSingleObjectReader {
+            a: 42,
+            b: 3.33,
+            c: vec!["cat".into(), "dog".into()],
+        };
+        let mut to_read = Vec::<u8>::new();
+        to_read.extend_from_slice(&[0xC3, 0x01]);
+        to_read.extend_from_slice(
+            &TestSingleObjectReader::get_schema()
+                .fingerprint::<Rabin>()
+                .bytes[..],
+        );
+        encode(
+            &obj.clone().into(),
+            &TestSingleObjectReader::get_schema(),
+            &mut to_read,
+        )
+        .expect("Encode should succeed");
+        let mut to_read = &to_read[..];
+        let generic_reader = 
GenericSingleObjectReader::new(TestSingleObjectReader::get_schema())
+            .expect("Schema should resolve");
+        let val = generic_reader
+            .read_value(&mut to_read)
+            .expect("Should read");
+        let expected_value: Value = obj.into();
+        assert_eq!(expected_value, val);
+    }
+
+    #[test]
+    fn test_reader_parity() {

Review Comment:
   ```suggestion
       fn test_avro_3507_reader_parity() {
   ```



##########
lang/rust/avro/src/reader.rs:
##########
@@ -569,4 +663,158 @@ mod tests {
         let reader = Reader::new(&result[..]).unwrap();
         assert_eq!(reader.user_metadata(), &user_meta_data);
     }
+
+    #[derive(Deserialize, Clone, PartialEq, Debug)]
+    struct TestSingleObjectReader {
+        a: i64,
+        b: f64,
+        c: Vec<String>,
+    }
+
+    impl AvroSchema for TestSingleObjectReader {
+        fn get_schema() -> Schema {
+            let schema = r#"
+            {
+                "type":"record",
+                "name":"TestSingleObjectWrtierSerialize",
+                "fields":[
+                    {
+                        "name":"a",
+                        "type":"long"
+                    },
+                    {
+                        "name":"b",
+                        "type":"double"
+                    },
+                    {
+                        "name":"c",
+                        "type":{
+                            "type":"array",
+                            "items":"string"
+                        }
+                    }
+                ]
+            }
+            "#;
+            Schema::parse_str(schema).unwrap()
+        }
+    }
+
+    impl From<Value> for TestSingleObjectReader {
+        fn from(obj: Value) -> TestSingleObjectReader {
+            if let Value::Record(fields) = obj {
+                let mut a = None;
+                let mut b = None;
+                let mut c = vec![];
+                for (field_name, v) in fields {
+                    match (field_name.as_str(), v) {
+                        ("a", Value::Long(i)) => a = Some(i),
+                        ("b", Value::Double(d)) => b = Some(d),
+                        ("c", Value::Array(v)) => {
+                            for inner_val in v {
+                                if let Value::String(s) = inner_val {
+                                    c.push(s);
+                                }
+                            }
+                        }
+                        _ => panic!("Unexpected pair"),
+                    }
+                }
+                TestSingleObjectReader {
+                    a: a.unwrap(),
+                    b: b.unwrap(),
+                    c,
+                }
+            } else {
+                panic!("Should be record value")
+            }
+        }
+    }
+
+    impl From<TestSingleObjectReader> for Value {
+        fn from(obj: TestSingleObjectReader) -> Value {
+            Value::Record(vec![
+                ("a".into(), obj.a.into()),
+                ("b".into(), obj.b.into()),
+                (
+                    "c".into(),
+                    Value::Array(obj.c.into_iter().map(|s| 
s.into()).collect()),
+                ),
+            ])
+        }
+    }
+
+    #[test]
+    fn test_single_object_reader() {

Review Comment:
   ```suggestion
       fn test_avro_3507_single_object_reader() {
   ```



##########
lang/rust/avro/src/error.rs:
##########
@@ -337,6 +337,9 @@ pub enum Error {
     #[error("wrong magic in header")]
     HeaderMagic,
 
+    #[error("Message Header mismatch. Expected: {0:?}. Actual: {1:?}")]
+    MessageHeaderMismatch([u8; 10], [u8; 10]),

Review Comment:
   SingleObjectHeaderMismatch ?!





Issue Time Tracking
-------------------

    Worklog Id:     (was: 767711)
    Time Spent: 20m  (was: 10m)

> [rust] Implement Single Object Reader
> -------------------------------------
>
>                 Key: AVRO-3507
>                 URL: https://issues.apache.org/jira/browse/AVRO-3507
>             Project: Apache Avro
>          Issue Type: New Feature
>            Reporter: Jack Klamer
>            Assignee: Jack Klamer
>            Priority: Major
>              Labels: pull-request-available
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> The spec contains a definition for Single object Encoding: 
> https://avro.apache.org/docs/current/spec.html#single_object_encoding
> Rust should have a compatible reader



--
This message was sent by Atlassian Jira
(v8.20.7#820007)

Reply via email to