Skip to main content

rusteal_codegen/rust_gen/
manual.rs

1// Hand-written binding extensions: glam conversions, FKey helpers, world and
2// widget wrappers.
3//
4// They live in this crate's `manual/` directory, are embedded at build time and
5// written verbatim into every generated `bindings` crate, where they compile
6// against the generated modules (`crate::core_ue`, `crate::engine`, ...).
7
8use std::path::Path;
9
10include!(concat!(env!("OUT_DIR"), "/manual_files.rs"));
11
12/// Write `src/manual/`, removing whatever else a previous run left behind.
13pub fn write_manual_module(src_dir: &Path) {
14    let manual_dir = src_dir.join("manual");
15    if let Ok(entries) = std::fs::read_dir(&manual_dir) {
16        for entry in entries.flatten() {
17            let name = entry.file_name();
18            if !MANUAL_FILES.iter().any(|(file, _)| name == *file) {
19                let path = entry.path();
20                let removed = if path.is_dir() {
21                    std::fs::remove_dir_all(&path)
22                } else {
23                    std::fs::remove_file(&path)
24                };
25                removed.unwrap_or_else(|e| panic!("Failed to clean {}: {e}", path.display()));
26            }
27        }
28    }
29    std::fs::create_dir_all(&manual_dir)
30        .unwrap_or_else(|e| panic!("Failed to create {}: {e}", manual_dir.display()));
31
32    for (name, contents) in MANUAL_FILES {
33        crate::write_if_changed(&manual_dir.join(name), contents)
34            .unwrap_or_else(|e| panic!("Failed to write manual/{name}: {e}"));
35    }
36    eprintln!("  manual/: {} files", MANUAL_FILES.len());
37}
38
39/// The Cargo features `manual/` gates its modules on (`#[cfg(feature = "...")]`).
40/// A project enables only some of them, so the generated manifest declares all
41/// of them as expected `cfg` values.
42pub fn gating_features() -> std::collections::BTreeSet<&'static str> {
43    const MARKER: &str = "feature = \"";
44    let mut features = std::collections::BTreeSet::new();
45    for (_, contents) in MANUAL_FILES {
46        let mut rest = *contents;
47        while let Some(at) = rest.find(MARKER) {
48            rest = &rest[at + MARKER.len()..];
49            if let Some(end) = rest.find('"') {
50                features.insert(&rest[..end]);
51                rest = &rest[end..];
52            }
53        }
54    }
55    features
56}