1use serde::{Deserialize, Serialize};
16
17use crate::error::{Error, Result};
18use crate::schema::{ColumnSchema, Schema, SchemaBuilder};
19
20#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
24pub struct RawSchema {
25 pub column_schemas: Vec<ColumnSchema>,
27 pub timestamp_index: Option<usize>,
29 pub version: u32,
31}
32
33impl RawSchema {
34 pub fn new(column_schemas: Vec<ColumnSchema>) -> RawSchema {
39 let timestamp_index = column_schemas
40 .iter()
41 .position(|column_schema| column_schema.is_time_index());
42
43 RawSchema {
44 column_schemas,
45 timestamp_index,
46 version: 0,
47 }
48 }
49}
50
51impl TryFrom<RawSchema> for Schema {
52 type Error = Error;
53
54 fn try_from(raw: RawSchema) -> Result<Schema> {
55 SchemaBuilder::try_from(raw.column_schemas)?
58 .version(raw.version)
59 .build()
60 }
61}
62
63impl From<&Schema> for RawSchema {
64 fn from(schema: &Schema) -> RawSchema {
65 RawSchema {
66 column_schemas: schema.column_schemas.clone(),
67 timestamp_index: schema.timestamp_index,
68 version: schema.version,
69 }
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use crate::data_type::ConcreteDataType;
77
78 #[test]
79 fn test_raw_convert() {
80 let column_schemas = vec![
81 ColumnSchema::new("col1", ConcreteDataType::int32_datatype(), true),
82 ColumnSchema::new(
83 "ts",
84 ConcreteDataType::timestamp_millisecond_datatype(),
85 false,
86 )
87 .with_time_index(true),
88 ];
89 let schema = SchemaBuilder::try_from(column_schemas)
90 .unwrap()
91 .version(123)
92 .build()
93 .unwrap();
94
95 let raw = RawSchema::from(&schema);
96 let schema_new = Schema::try_from(raw).unwrap();
97
98 assert_eq!(schema, schema_new);
99 }
100
101 #[test]
102 fn test_new_raw_schema_with_time_index() {
103 let column_schemas = vec![
104 ColumnSchema::new("col1", ConcreteDataType::int32_datatype(), true),
105 ColumnSchema::new(
106 "ts",
107 ConcreteDataType::timestamp_millisecond_datatype(),
108 false,
109 )
110 .with_time_index(true),
111 ];
112 let schema = RawSchema::new(column_schemas);
113 assert_eq!(1, schema.timestamp_index.unwrap());
114 }
115
116 #[test]
117 fn test_new_raw_schema_without_time_index() {
118 let column_schemas = vec![
119 ColumnSchema::new("col1", ConcreteDataType::int32_datatype(), true),
120 ColumnSchema::new(
121 "ts",
122 ConcreteDataType::timestamp_millisecond_datatype(),
123 false,
124 ),
125 ];
126 let schema = RawSchema::new(column_schemas);
127 assert!(schema.timestamp_index.is_none());
128 }
129}