1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use std::fs::File;
use serde_yaml::Error;
use crate::DType;

#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct Schema {
    pub name: String,
    pub dataset: DataSet,
}

#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct DataSet {
    pub name: String,
    pub columns: Vec<Column>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct Column {
    pub name: String,
    pub not_null: Option<bool>,
    pub dtype: DType,
}

impl Schema {
    pub fn from(s: &str) -> Result<Schema, Error> {
        serde_yaml::from_str(s)
    }

    pub fn from_path(path: String) -> Result<Schema, Error> {
        let file = File::open(path).expect("Unable to open the file");
        serde_yaml::from_reader(file)
    }
}

#[cfg(test)]
mod tests {
    use crate::schema::Schema;

    #[test]
    fn derive_struct_from_yaml() {
        let yaml = r#"name: person_schema
dataset:
    name: person_table
    columns:
        -
            name: id
            not_null: false
            dtype: int
        -
            name: name
            dtype: string
        -
            name: age
            dtype: int
        -
            name: adult
            default: 'false'
            dtype: boolean
        -
            name: gender
            dtype: gender
"#;

        let schema = Schema::from(&yaml);
        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 }, Column { name: "name", not_null: None, dtype: String }, Column { name: "age", not_null: None, dtype: Int }, Column { name: "adult", not_null: None, dtype: Boolean }, Column { name: "gender", not_null: None, dtype: Gender }] } }"#);
    }

    #[test]
    fn derive_struct_from_file() {
        let file_path = "./test_data/schema_simple.yaml".to_string();
        let schema = Schema::from_path(file_path);
        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 }, Column { name: "name", not_null: None, dtype: Name }, Column { name: "age", not_null: None, dtype: Age }, Column { name: "adult", not_null: None, dtype: Boolean }, Column { name: "gender", not_null: None, dtype: Gender }] } }"#);
    }
}