Skip to content

Unable to make it work for nested types in different Schema Files. #44

@markfarnan

Description

@markfarnan

Looking for guidance on how to make rsgen-Avro and avro-rust work when there are multiple schema files, where one file relies on a type in another file.

rsgen-avro seems to create the schema's correctly.
Schema::parse_list seems to parse the schema's correct.

Writer throws validation errors. (i've also trying using more lower level primatives, such as to_avro_datum, same issue)
Line 81 in the sample code below: Err(SchemaResolutionError(Name { name: "ErrorInfo", namespace: Some("Energistics.Etp.v12.Datatypes") }))

Sample code to show the issue:
NOTES:
-- This is a subset of what I need to do. The full Schema definition I need to use is 200+ .AVSC files, with multiple nested / reused types.
-- I can't change the structure of the Schema files, as this is a Published Industry Standard in our domain for data interchange using a wire protocol. (I will actually use to_avro_datum for the final version, as we just want the raw bytes, not the headers etc).
-- I'm getting some other errors with the rsgen (serde-bytes, and unable to use derive-schemas) that might post seperatly. I can share the full set of schema's if it is usefull for debugging.

Sample code showing the problem.


// Test File
use apache_avro::{Schema, Writer};

// Structs Generated from rsgen-avro with commandline -->   rsgen-avro  "*.avsc" schema.rs
// Interestingly trying to use "--nullable" in rsgen-avro throws an error "Templating error: Failed to render 'record.tera'" might need to look at that seperatly.
//
#[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)]
pub struct ProtocolException {
   pub error: Option<ErrorInfo>,
   #[serde(default = "default_protocolexception_errors")]
   pub errors: ::std::collections::HashMap<String, ErrorInfo>,
}

#[inline(always)]
fn default_protocolexception_errors() -> ::std::collections::HashMap<String, ErrorInfo> {
   ::std::collections::HashMap::new()
}

#[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize)]
pub struct ErrorInfo {
   pub message: String,
   pub code: i32,
}

// Main Test
fn main() {
   let errinfo_schema = r#"
   {
       "type": "record",
       "namespace": "Energistics.Etp.v12.Datatypes",
       "name": "ErrorInfo",
       "fields":
       [
           { "name": "message", "type": "string" },
           { "name": "code", "type": "int" }
       ]
   }
   "#;

   let protocolexception_schema = r#"
   {
       "type": "record",
       "namespace": "Energistics.Etp.v12.Protocol.Core",
       "name": "ProtocolException",
       "protocol": "0",
       "messageType": "1000",
       "senderRole": "*",
       "protocolRoles": "client, server",
       "multipartFlag": true,
       "fields":
       [
           { "name": "error", "type": ["null", "Energistics.Etp.v12.Datatypes.ErrorInfo"] },
           {
               "name": "errors",
               "type": { "type": "map", "values": "Energistics.Etp.v12.Datatypes.ErrorInfo" }, "default": {}
           }
       ]
   }
   "#;

   let schema_list: [&str; 2] = [protocolexception_schema, errinfo_schema];
   let schemas_raw = Schema::parse_list(&schema_list);

   println!("{:?}", schemas_raw);
   println!("{:?}", "--------------");

   let schemas = schemas_raw.unwrap();

   let pe = ProtocolException {
       error: Some(ErrorInfo {
           message: String::from("some Error Message"),
           code: 451,
       }),
       errors: ::std::collections::HashMap::new(),
   };

   println!("{:?}", schemas[0]); // The 'ProtocolException' Schema in the list
   println!("{:?}", "--------------");

   let mut writer = Writer::new(&schemas[0], Vec::new()); // <-- Should I be able to pass the 'list' of Schema's here somewhere, so it resolves all the sub types ?

   let result = writer.append_ser(pe); // <-- Schema Resolution Error !  Missing the ErrorInfo Subtype
   println!("{:?}", result);

   let encoded = writer.into_inner();
   println!("{:?}", encoded);

   // Equivelent READER code to go here, once WRITER works.
}


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions