use serde::{Deserialize, Serialize};
use crate::error::Error;
use super::types::StructType;
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all = "kebab-case")]
pub struct Schema {
pub schema_id: i32,
#[serde(skip_serializing_if = "Option::is_none")]
pub identifier_field_ids: Option<Vec<i32>>,
#[serde(flatten)]
pub fields: StructType,
}
impl TryFrom<SchemaV2> for Schema {
type Error = Error;
fn try_from(value: SchemaV2) -> Result<Self, Self::Error> {
Ok(Schema {
schema_id: value.schema_id,
identifier_field_ids: value.identifier_field_ids,
fields: value.fields,
})
}
}
impl TryFrom<SchemaV1> for Schema {
type Error = Error;
fn try_from(value: SchemaV1) -> Result<Self, Self::Error> {
Ok(Schema {
schema_id: value.schema_id.unwrap_or(0),
identifier_field_ids: value.identifier_field_ids,
fields: value.fields,
})
}
}
impl From<Schema> for SchemaV2 {
fn from(value: Schema) -> Self {
SchemaV2 {
schema_id: value.schema_id,
identifier_field_ids: value.identifier_field_ids,
fields: value.fields,
}
}
}
impl From<Schema> for SchemaV1 {
fn from(value: Schema) -> Self {
SchemaV1 {
schema_id: Some(value.schema_id),
identifier_field_ids: value.identifier_field_ids,
fields: value.fields,
}
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all = "kebab-case")]
pub struct SchemaV2 {
pub schema_id: i32,
#[serde(skip_serializing_if = "Option::is_none")]
pub identifier_field_ids: Option<Vec<i32>>,
#[serde(flatten)]
pub fields: StructType,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all = "kebab-case")]
pub struct SchemaV1 {
#[serde(skip_serializing_if = "Option::is_none")]
pub schema_id: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub identifier_field_ids: Option<Vec<i32>>,
#[serde(flatten)]
pub fields: StructType,
}
impl From<SchemaV1> for SchemaV2 {
fn from(v1: SchemaV1) -> Self {
SchemaV2 {
schema_id: v1.schema_id.unwrap_or(0),
identifier_field_ids: v1.identifier_field_ids,
fields: v1.fields,
}
}
}
#[cfg(test)]
mod tests {
use crate::spec::types::{PrimitiveType, Type};
use super::*;
#[test]
fn schema() {
let record = r#"
{
"type": "struct",
"schema-id": 1,
"fields": [ {
"id": 1,
"name": "id",
"required": true,
"type": "uuid"
}, {
"id": 2,
"name": "data",
"required": false,
"type": "int"
} ]
}
"#;
let result: SchemaV2 = serde_json::from_str(record).unwrap();
assert_eq!(1, result.schema_id);
assert_eq!(
Type::Primitive(PrimitiveType::Uuid),
result.fields[0].field_type
);
assert_eq!(1, result.fields[0].id);
assert!(result.fields[0].required);
assert_eq!(
Type::Primitive(PrimitiveType::Int),
result.fields[1].field_type
);
assert_eq!(2, result.fields[1].id);
assert!(!result.fields[1].required);
}
}