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
#![feature(proc_macro_span, register_tool)]
#![register_tool(tarpaulin)]
mod keys;
mod utils;
use keys::*;
use utils::{get_attribute, Result};
use std::path::Path;
use syn::parse_macro_input;
use yaml_rust::Yaml;
#[tarpaulin::skip]
#[proc_macro_attribute]
pub fn kaitai_source(
args: proc_macro::TokenStream,
item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
let ks_source_path = parse_macro_input!(args as syn::LitStr);
let item_ast = parse_macro_input!(item as syn::Item);
let struct_item = match item_ast {
syn::Item::Struct(s) => s,
_ => {
panic!("attribute not on struct");
}
};
match &struct_item.fields {
syn::Fields::Unit => {}
_ => {
panic!("struct has fields");
}
}
let mut source_file_path = proc_macro::Span::call_site().source_file().path();
source_file_path.pop();
let file_path = source_file_path.join(Path::new(&ks_source_path.value()));
let file_contents = std::fs::read_to_string(file_path).expect("error reading file: ");
let structure =
&yaml_rust::YamlLoader::load_from_str(&file_contents).expect("error parsing file: ")[0];
let result = match structure {
Yaml::Hash(map) => types::gen_type(&types::TypeInfo {
map,
ident: struct_item.ident,
attrs: struct_item.attrs,
visibility: struct_item.vis,
inherited_meta: None,
}),
_ => panic!("file does not have the correct structure"),
};
result.unwrap().into()
}