use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("generated_types.rs");
let mut file = File::create(&dest_path).unwrap();
let content = std::fs::read_to_string("matroska-specification/ebml_matroska.xml").unwrap();
let doc = roxmltree::Document::parse(&content).unwrap();
for element in doc
.descendants()
.filter(|n| n.has_tag_name("element"))
.filter(|n| n.attribute("type") != Some("master"))
{
let name = element.attribute("name").unwrap();
let id = element.attribute("id").unwrap();
let (ty, rep_ty) = match element.attribute("type").unwrap() {
"uinteger" => ("UnsignedInteger", "u64"),
"integer" => ("SignedInteger", "i64"),
"string" => ("Text", "&'static str"),
"utf-8" => ("Text", "&'static str"),
"binary" => ("Bin", "&'static [u8]"),
"float" => ("Float", "f64"),
"date" => ("Date", "&'static [u8]"), other => panic!("Unknown type: {other}"),
};
let default_value = element.attribute("default");
let documentation = element
.children()
.find(|n| n.has_tag_name("documentation"))
.and_then(|n| n.text());
if let Some(doc) = documentation {
for line in doc.lines() {
writeln!(
file,
"/// {}",
line.trim().replace("[", "\\[").replace("]", "\\]")
)
.unwrap();
}
} else {
writeln!(file, "/// {name} in ebml").unwrap();
}
writeln!(file, "pub type {name} = {ty}<{id}>;").unwrap();
writeln!(file, "impl {name} {{").unwrap();
if let Some(default) = default_value {
writeln!(file, "/// Default value for the element if not present.").unwrap();
if ty == "Float" {
writeln!(
file,
" pub const DEFAULT: Option<{rep_ty}> = Some(hexf::hexf64!(\"{default}\"));"
)
.unwrap();
} else if ty == "Text" {
writeln!(
file,
" pub const DEFAULT: Option<{rep_ty}> = Some(\"{default}\");"
)
.unwrap();
} else {
writeln!(
file,
" pub const DEFAULT: Option<{rep_ty}> = Some({default});"
)
.unwrap();
}
} else {
writeln!(file, "/// Does not have a default value").unwrap();
writeln!(file, " pub const DEFAULT: Option<{rep_ty}> = None;").unwrap();
}
writeln!(file, "}}").unwrap();
}
}