use rvt::{RevitFile, compression, formats, streams};
use std::collections::BTreeMap;
fn main() {
let mut paths: Vec<String> = Vec::new();
let family_dir = std::env::var("RVT_SAMPLES_DIR").unwrap_or_else(|_| "../../samples".into());
if let Ok(entries) = std::fs::read_dir(&family_dir) {
for e in entries.flatten() {
let p = e.path();
if p.extension().is_some_and(|x| x == "rfa" || x == "rvt") {
paths.push(p.to_string_lossy().into_owned());
}
}
}
if let Ok(proj) = std::env::var("RVT_PROJECT_CORPUS_DIR") {
if let Ok(entries) = std::fs::read_dir(&proj) {
for e in entries.flatten() {
let p = e.path();
if p.extension().is_some_and(|x| x == "rvt") {
paths.push(p.to_string_lossy().into_owned());
}
}
}
}
if paths.is_empty() {
eprintln!(
"no corpus files found. Set RVT_SAMPLES_DIR or \
RVT_PROJECT_CORPUS_DIR to point at a .rvt/.rfa directory."
);
return;
}
let mut by_kind: BTreeMap<u8, Vec<(String, String, String)>> = BTreeMap::new();
for path in &paths {
let Ok(mut rf) = RevitFile::open(path) else {
continue;
};
let Ok(raw) = rf.read_stream(streams::FORMATS_LATEST) else {
continue;
};
let Ok((_, d)) = compression::inflate_at_auto(&raw) else {
continue;
};
let Ok(schema) = formats::parse_schema(&d) else {
continue;
};
let file_name = path.rsplit('/').next().unwrap_or(path).to_string();
for cls in &schema.classes {
for f in &cls.fields {
if let Some(formats::FieldType::Container { kind, .. }) = &f.field_type {
by_kind.entry(*kind).or_default().push((
file_name.clone(),
cls.name.clone(),
f.name.clone(),
));
}
}
}
}
println!(
"=== Container kind histogram across {} files ===",
paths.len()
);
for (kind, examples) in &by_kind {
println!(
"\nkind 0x{kind:02x}: {} occurrences, {} distinct (file, class, field) triples",
examples.len(),
{
let mut unique: std::collections::BTreeSet<(String, String, String)> =
std::collections::BTreeSet::new();
unique.extend(examples.iter().cloned());
unique.len()
}
);
for (file, class, field) in examples.iter().take(5) {
println!(" {file} → {class}.{field}");
}
if examples.len() > 5 {
println!(" … {} more", examples.len() - 5);
}
}
}