diff --git a/rust/Cargo.toml b/rust/Cargo.toml index d000445e67e02..b8750945fb162 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -36,6 +36,8 @@ path = "src/lib.rs" [dependencies] bytes = "0.4" libc = "0.2" +serde = { version = "1.0.80", features = ["alloc", "rc"] } +serde_derive = "1.0.80" serde_json = "1.0.13" rand = "0.5" csv = "1.0.0" diff --git a/rust/src/datatypes.rs b/rust/src/datatypes.rs index ec9b852b5b242..a9bd855f059fe 100644 --- a/rust/src/datatypes.rs +++ b/rust/src/datatypes.rs @@ -39,7 +39,7 @@ use serde_json::Value; /// Nested types can themselves be nested within other arrays. /// For more information on these types please see /// [here](https://arrow.apache.org/docs/memory_layout.html). -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub enum DataType { Boolean, Int8, @@ -61,7 +61,7 @@ pub enum DataType { /// Contains the meta-data for a single relative type. /// /// The `Schema` object is an ordered collection of `Field` objects. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub struct Field { name: String, data_type: DataType, @@ -300,7 +300,7 @@ impl fmt::Display for Field { /// /// Note that this information is only part of the meta-data and not part of the physical memory /// layout. -#[derive(Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct Schema { fields: Vec, } @@ -382,6 +382,42 @@ mod tests { ]); } + #[test] + fn serde_struct_type() { + let person = DataType::Struct(vec![ + Field::new("first_name", DataType::Utf8, false), + Field::new("last_name", DataType::Utf8, false), + Field::new( + "address", + DataType::Struct(vec![ + Field::new("street", DataType::Utf8, false), + Field::new("zip", DataType::UInt16, false), + ]), + false, + ), + ]); + + let serialized = serde_json::to_string(&person).unwrap(); + + // NOTE that this is testing the default (derived) serialization format, not the + // JSON format specified in metadata.md + + assert_eq!( + "{\"Struct\":[\ + {\"name\":\"first_name\",\"data_type\":\"Utf8\",\"nullable\":false},\ + {\"name\":\"last_name\",\"data_type\":\"Utf8\",\"nullable\":false},\ + {\"name\":\"address\",\"data_type\":{\"Struct\":\ + [{\"name\":\"street\",\"data_type\":\"Utf8\",\"nullable\":false},\ + {\"name\":\"zip\",\"data_type\":\"UInt16\",\"nullable\":false}\ + ]},\"nullable\":false}]}", + serialized + ); + + let deserialized = serde_json::from_str(&serialized).unwrap(); + + assert_eq!(person, deserialized); + } + #[test] fn struct_field_to_json() { let f = Field::new( diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 859b0a1750b7f..cc6d3ff73f1ab 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -19,9 +19,14 @@ extern crate bytes; extern crate csv as csv_crate; extern crate libc; +#[macro_use] +extern crate serde_derive; + #[macro_use] extern crate serde_json; +extern crate serde; + extern crate rand; pub mod array;