carta_schema/
lib.rs

1/*!
2 * Compiler - Compile .carta schema files into a usable internal representation that can be
3 * applied to binary files.
4 *
5 * Stages of compilation:
6 *
7 * Tokenisation        Split the input file into Tokens
8 *      |
9 *      V
10 *   Parsing           Extract file structure definitions.  Returns a schema object that contains
11 *      |              a list of the structs, in the order they appeared in the input file.
12 *      V
13 * Type checking       Uses the StructDefns and builtin types to do type checking. Returns
14 *      |              a tschema object with type checked types.
15 *      V
16 * Correctness Checks  Final checks on the schema.
17 *      |               - Root element is correctly present
18 *      |               - Array lengths can be calculated
19 *      V
20 * Final schema
21 */
22
23mod apply;
24mod builtin_types;
25mod correctness;
26mod error;
27mod parser;
28mod tokeniser;
29mod type_check;
30
31pub use apply::Nugget;
32use error::CartaError;
33pub use type_check::TSchema;
34
35pub fn compile_schema_file(data: &str) -> Result<TSchema, CartaError> {
36    let tokeniser = tokeniser::Tokeniser::new(&data)?;
37    let schema = parser::compile_schema(tokeniser)?;
38    let tschema = type_check::type_check_schema(schema)?;
39    correctness::check_schema(&tschema)?;
40    Ok(tschema)
41}
42
43pub fn apply_schema(schema: &TSchema, file_data: &[u8]) -> Nugget {
44    apply::apply_schema(schema, file_data)
45}
46
47#[cfg(test)]
48mod test {
49    use super::*;
50
51    #[test]
52    fn basic_compile_and_apply() {
53        let schema = compile_schema_file("struct root {new_name: int8}").unwrap();
54        apply_schema(&schema, b"\x00");
55    }
56
57    #[test]
58    fn all_types() {
59        let schema = compile_schema_file(
60            "struct root {
61                int8: int8,
62                be: be,
63                le: le
64            }
65            struct be {
66                i_16: int16_be,
67                i_32: int32_be,
68                i_64: int64_be,
69                u_16: uint16_be,
70                u_32: uint32_be,
71                u_64: uint64_be,
72                f_32: f32_be,
73                f_64: f64_be,
74                arr: [int16_be; i_16]
75            }
76            struct le {
77                int16: int16_le,
78                int32: int32_le,
79                int64: int64_le,
80                uint16: uint16_le,
81                uint32: uint32_le,
82                uint64: uint64_le,
83                f32: f32_le,
84                f64: f64_le,
85            }
86        ",
87        )
88        .unwrap();
89        apply_schema(&schema, &[0; 83]);
90    }
91}