build.rs 2.87 KB
Newer Older
Sven Liefgen's avatar
Sven Liefgen committed
1
2
3
4
5
6
7
use std::env;
use std::fs;
use std::path::Path;

use yaml_rust::YamlLoader;

fn main() {
Sven Liefgen's avatar
Sven Liefgen committed
8
9
10
    let out_dir = env::var("OUT_DIR").unwrap();
    let dest_path = Path::new(&out_dir).join("xlap_generated.rs");

11
    if let Ok(xlap) = env::var("XLAP") {
Sven Liefgen's avatar
Sven Liefgen committed
12
        let yaml = fs::read_to_string(&xlap).expect("Could not read file");
Sven Liefgen's avatar
Sven Liefgen committed
13

Sven Liefgen's avatar
Sven Liefgen committed
14
        let yaml = YamlLoader::load_from_str(yaml.as_str())
Sven Liefgen's avatar
Sven Liefgen committed
15
            .expect("Could not load yml")
Sven Liefgen's avatar
Sven Liefgen committed
16
            .pop()
Sven Liefgen's avatar
Sven Liefgen committed
17
            .expect("No documents in yml");
Sven Liefgen's avatar
Sven Liefgen committed
18

19
        // Create XLAP array containing a table for each kind
Sven Liefgen's avatar
Sven Liefgen committed
20

21
        let packet_types = &yaml["packet_types"];
22
23
24
25
        let packet_types_count = packet_types
            .as_hash()
            .expect("Expected `packet_types to be a `Hash`")
            .len();
Sven Liefgen's avatar
Sven Liefgen committed
26

Sven Liefgen's avatar
Sven Liefgen committed
27
28
29
30
        let mut static_xlap = format!(
            "static XLAP: [AtomicPtr<TimestampTable>; {}] = [\n",
            packet_types_count
        );
31
32
33
34
35
36
37
        for _ in 0..packet_types_count {
            static_xlap.push_str("    AtomicPtr::new(std::ptr::null_mut()),\n");
        }
        static_xlap.push_str("];\n");

        // Create constants for kinds

Sven Liefgen's avatar
Cleanup    
Sven Liefgen committed
38
39
40
41
42
43
44
        let mut kind_enum = String::from("#[derive(EnumIter, Copy, Clone)]\n");
        kind_enum.push_str("#[allow(non_camel_case_types)]\n");
        kind_enum.push_str("pub enum Kind {\n");
        for kind in packet_types.as_hash().unwrap().keys() {
            kind_enum.push_str("    TS_");
            kind_enum.push_str(kind.as_str().unwrap().to_uppercase().as_str());
            kind_enum.push_str(",\n");
45
        }
Sven Liefgen's avatar
Cleanup    
Sven Liefgen committed
46
        kind_enum.push_str("}\n");
47
48

        // Create timestamps
Sven Liefgen's avatar
Sven Liefgen committed
49

50
        let timestamps = &yaml["stamps"];
Sven Liefgen's avatar
Sven Liefgen committed
51

52
53
        let mut timestamp_id_enum =
            String::from("#[derive(EnumCount, EnumIter, AsRefStr, Copy, Clone)]\n");
54
        timestamp_id_enum.push_str("pub enum TimestampId {\n");
55
56
57
58
59
        for timestamp_id in timestamps
            .as_hash()
            .expect("Expected `stamps` to be a `Hash`")
            .keys()
        {
60
61
62
63
64
            timestamp_id_enum.push_str("    ");
            timestamp_id_enum.push_str(timestamp_id.as_str().unwrap());
            timestamp_id_enum.push_str(",\n");
        }
        timestamp_id_enum.push_str("}\n");
Sven Liefgen's avatar
Sven Liefgen committed
65

Sven Liefgen's avatar
Sven Liefgen committed
66
67
68
69
        // Create TS_ROWS

        let count = &yaml["rows"].as_i64().unwrap_or(4098);

Sven Liefgen's avatar
Sven Liefgen committed
70
        let ts_rows = format!("const TS_ROWS: usize = {};\n", count + 1);
Sven Liefgen's avatar
Sven Liefgen committed
71

72
73
        fs::write(
            &dest_path,
Sven Liefgen's avatar
Sven Liefgen committed
74
75
            format!(
                "{}\n{}\n{}\n{}\n",
Sven Liefgen's avatar
Cleanup    
Sven Liefgen committed
76
                ts_rows, static_xlap, kind_enum, timestamp_id_enum,
Sven Liefgen's avatar
Sven Liefgen committed
77
78
79
            ),
        )
        .unwrap();
Sven Liefgen's avatar
Sven Liefgen committed
80
        println!("cargo:rerun-if-changed={}", xlap);
81
82
    } else if !dest_path.exists() {
        panic!("Specify the absolute path to your `xlap.yml` using the `XLAP` environment variable on the first build");
Sven Liefgen's avatar
Sven Liefgen committed
83
    }
84
85
86
    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed=src/lib.rs");
    println!("cargo:rerun-if-env-changed=XLAP");
Sven Liefgen's avatar
Sven Liefgen committed
87
}