1use std::fs::File;
2use serde_yaml::Error;
3use crate::DType;
4
5#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
6pub struct Schema {
7 pub name: String,
8 pub dataset: DataSet,
9}
10
11#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
12pub struct DataSet {
13 pub name: String,
14 pub columns: Vec<Column>,
15}
16
17#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
18pub struct Column {
19 pub name: String,
20 pub not_null: Option<bool>,
21 pub dtype: DType,
22 pub one_of: Option<Vec<String>>,
23 pub min: Option<String>,
24 pub max: Option<String>,
25 pub mean: Option<f64>,
26 pub std: Option<f64>,
27 pub format: Option<String>
28
29}
30
31impl Schema {
32 pub fn from(s: &str) -> Result<Schema, Error> {
33 serde_yaml::from_str(s)
34 }
35
36 pub fn from_path(path: String) -> Result<Schema, Error> {
37 let file = File::open(path).expect("Unable to open the file");
38 serde_yaml::from_reader(file)
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use crate::schema::Schema;
45
46 #[test]
47 fn derive_struct_from_yaml() {
48 let yaml = r#"name: person_schema
49dataset:
50 name: person_table
51 columns:
52 -
53 name: id
54 not_null: false
55 dtype: int
56 -
57 name: name
58 dtype: string
59 -
60 name: age
61 dtype: int
62 -
63 name: adult
64 default: 'false'
65 dtype: boolean
66 -
67 name: gender
68 dtype: string
69"#;
70
71 let schema = Schema::from(&yaml);
72 pretty_assertions::assert_eq!(format ! ("{:?}", schema.unwrap()), r#"Schema { name: "person_schema", dataset: DataSet { name: "person_table", columns: [Column { name: "id", not_null: Some(false), dtype: Int, one_of: None, min: None, max: None, mean: None, std: None, format: None }, Column { name: "name", not_null: None, dtype: String, one_of: None, min: None, max: None, mean: None, std: None, format: None }, Column { name: "age", not_null: None, dtype: Int, one_of: None, min: None, max: None, mean: None, std: None, format: None }, Column { name: "adult", not_null: None, dtype: Boolean, one_of: None, min: None, max: None, mean: None, std: None, format: None }, Column { name: "gender", not_null: None, dtype: String, one_of: None, min: None, max: None, mean: None, std: None, format: None }] } }"#);
73 }
74
75 #[test]
76 fn derive_struct_from_file() {
77 let file_path = "./test_data/schema_simple.yaml".to_string();
78 let schema = Schema::from_path(file_path);
79 pretty_assertions::assert_eq!(format!("{:?}", schema.unwrap()), r#"Schema { name: "person_schema", dataset: DataSet { name: "person_table", columns: [Column { name: "id", not_null: Some(false), dtype: Int, one_of: None, min: None, max: None, mean: None, std: None, format: None }, Column { name: "name", not_null: None, dtype: Name, one_of: None, min: None, max: None, mean: None, std: None, format: None }, Column { name: "age", not_null: None, dtype: Age, one_of: None, min: None, max: None, mean: None, std: None, format: None }, Column { name: "adult", not_null: None, dtype: Boolean, one_of: None, min: None, max: None, mean: None, std: None, format: None }, Column { name: "gender", not_null: None, dtype: String, one_of: Some(["M", "F"]), min: None, max: None, mean: None, std: None, format: None }, Column { name: "date", not_null: None, dtype: Date, one_of: None, min: Some("01/01/2014"), max: Some("03/01/2014"), mean: None, std: None, format: Some("%d/%m/%Y") }] } }"#);
80 }
81}