diff options
Diffstat (limited to 'opengl-bindings/build.rs')
| -rw-r--r-- | opengl-bindings/build.rs | 107 | 
1 files changed, 107 insertions, 0 deletions
diff --git a/opengl-bindings/build.rs b/opengl-bindings/build.rs new file mode 100644 index 0000000..060472c --- /dev/null +++ b/opengl-bindings/build.rs @@ -0,0 +1,107 @@ +use std::collections::HashSet; +use std::env; +use std::fs::File; +use std::path::{Path, PathBuf}; + +use anyhow::anyhow; +use gl_generator::{Api, Fallbacks, Profile, Registry, StructGenerator}; + +fn main() -> Result<(), anyhow::Error> +{ +    println!("cargo::rerun-if-changed=build.rs"); +    println!("cargo::rerun-if-changed=Cargo.toml"); + +    let dest = env::var("OUT_DIR")?; + +    let mut file = File::create(Path::new(&dest).join("bindings.rs"))?; + +    let mut registry = Registry::new(Api::Gl, (4, 6), Profile::Core, Fallbacks::All, []); + +    let mut build_metadata = get_build_metadata()?; + +    filter_gl_commands(&mut registry, &mut build_metadata)?; + +    registry.write_bindings(StructGenerator, &mut file)?; + +    Ok(()) +} + +fn filter_gl_commands( +    registry: &mut Registry, +    build_metadata: &mut BuildMetadata, +) -> Result<(), anyhow::Error> +{ +    registry +        .cmds +        .retain(|command| build_metadata.gl_commands.remove(&command.proto.ident)); + +    if !build_metadata.gl_commands.is_empty() { +        return Err(anyhow!( +            "Invalid GL commands: [{}]", +            build_metadata +                .gl_commands +                .iter() +                .cloned() +                .collect::<Vec<_>>() +                .join(", ") +        )); +    } + +    Ok(()) +} + +fn get_build_metadata() -> Result<BuildMetadata, anyhow::Error> +{ +    let manifest_path = PathBuf::from(std::env::var("CARGO_MANIFEST_PATH")?); + +    let manifest = std::fs::read_to_string(manifest_path)?.parse::<toml::Table>()?; + +    let package = match manifest +        .get("package") +        .ok_or_else(|| anyhow!("Manifest does not have a package table"))? +    { +        toml::Value::Table(package) => Ok(package), +        _ => Err(anyhow!("Manifest package must be a table")), +    }?; + +    let metadata = match package +        .get("metadata") +        .ok_or_else(|| anyhow!("Manifest does not have a package.metadata table"))? +    { +        toml::Value::Table(metadata) => Ok(metadata), +        _ => Err(anyhow!("Manifest package.metadata must be a table")), +    }?; + +    let build_metadata = match metadata +        .get("build") +        .ok_or_else(|| anyhow!("Manifest does not have a package.metadata.build table"))? +    { +        toml::Value::Table(build_metadata) => Ok(build_metadata), +        _ => Err(anyhow!("Manifest package.metadata.build must be a table")), +    }?; + +    let gl_command_values = match build_metadata.get("gl_commands").ok_or_else(|| { +        anyhow!("Manifest does not have a package.metadata.build.gl_commands array") +    })? { +        toml::Value::Array(gl_commands) => Ok(gl_commands), +        _ => Err(anyhow!( +            "Manifest package.metadata.build.gl_commands must be a array" +        )), +    }?; + +    let gl_commands = gl_command_values +        .iter() +        .map(|gl_command_val| match gl_command_val { +            toml::Value::String(gl_command) => Ok(gl_command.clone()), +            _ => Err(anyhow!("GL command must be a string")), +        }) +        .collect::<Result<HashSet<_>, _>>()?; + +    Ok(BuildMetadata { gl_commands }) +} + +#[derive(Debug)] +struct BuildMetadata +{ +    gl_commands: HashSet<String>, +}  | 
