Skip to content

Commit

Permalink
Use automatically generated 1.71 bindings from 0.1-dev
Browse files Browse the repository at this point in the history
This is the minimal first step that compiles but doesn't work
  • Loading branch information
Gekkio committed Jun 26, 2019
1 parent 3721aca commit 3ca1b7b
Show file tree
Hide file tree
Showing 11 changed files with 11,107 additions and 1,071 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ members = [
exclude = [
"imgui-examples",
"imgui-glium-examples",
"imgui-sys-bindgen"
]
16 changes: 16 additions & 0 deletions imgui-sys-bindgen/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "imgui-sys-bindgen"
version = "0.0.0"
authors = ["Joonas Javanainen <[email protected]>", "imgui-rs contributors"]
description = "imgui-sys bindings updater"
homepage = "https://github.com/Gekkio/imgui-rs"
repository = "https://github.com/Gekkio/imgui-rs"
license = "MIT/Apache-2.0"
publish = false

[dependencies]
bindgen = "0.49"
failure = "0.1"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
120 changes: 120 additions & 0 deletions imgui-sys-bindgen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
extern crate bindgen;
#[macro_use]
extern crate failure;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

use bindgen::{Bindings, EnumVariation, RustTarget};
use failure::Error;
use std::collections::HashMap;
use std::fs::{read_to_string, File};
use std::io::Read;
use std::path::Path;

#[derive(Deserialize)]
struct StructsAndEnums {
enums: HashMap<String, serde_json::Value>,
structs: HashMap<String, serde_json::Value>,
}

#[derive(Deserialize)]
struct DefinitionArg {
#[serde(rename = "type")]
type_: String,
}

#[derive(Deserialize)]
struct Definition {
#[serde(rename = "argsT")]
args_t: Vec<DefinitionArg>,
ov_cimguiname: String,
#[serde(rename = "nonUDT")]
non_udt: Option<u32>,
}

#[derive(Debug, Clone)]
struct Whitelist {
enums: Vec<String>,
structs: Vec<String>,
definitions: Vec<String>,
}

fn only_key<K, V>((key, _): (K, V)) -> K {
key
}

fn parse_whitelist<R: Read>(
structs_and_enums: R,
definitions: R,
) -> Result<Whitelist, serde_json::Error> {
let StructsAndEnums { enums, structs } = serde_json::from_reader(structs_and_enums)?;
let enums = enums.into_iter().map(only_key).collect();
let structs = structs.into_iter().map(only_key).collect();

let definitions: HashMap<String, Vec<Definition>> = serde_json::from_reader(definitions)?;
let definitions = definitions
.into_iter()
.flat_map(|(_, defs)| {
let require_non_udt = defs.iter().any(|def| def.non_udt.is_some());
defs.into_iter()
.filter(move |def| !require_non_udt || def.non_udt.is_some())
})
.filter_map(|d| {
let uses_va_list = d.args_t.iter().any(|a| a.type_ == "va_list");
if uses_va_list {
None
} else {
Some(d.ov_cimguiname)
}
})
.collect();

Ok(Whitelist {
enums,
structs,
definitions,
})
}

pub fn generate_bindings<P: AsRef<Path>>(cimgui_path: &P) -> Result<Bindings, Error> {
let cimgui_output_path = cimgui_path.as_ref().join("generator").join("output");
let structs_and_enums = File::open(cimgui_output_path.join("structs_and_enums.json"))?;
let definitions = File::open(cimgui_output_path.join("definitions.json"))?;
let header = read_to_string(cimgui_output_path.join("cimgui.h"))?;

let whitelist = parse_whitelist(structs_and_enums, definitions)?;
let mut builder = bindgen::builder()
.raw_line("#![allow(non_upper_case_globals)]")
.raw_line("#![allow(non_camel_case_types)]")
.raw_line("#![allow(non_snake_case)]")
.raw_line("#![allow(clippy::all)]")
.header_contents("cimgui.h", &header)
.rust_target(RustTarget::Stable_1_28)
.default_enum_style(EnumVariation::Consts)
.prepend_enum_name(false)
.generate_comments(false)
.layout_tests(true)
.derive_copy(true)
.derive_debug(true)
.derive_default(true)
.derive_hash(true)
.derive_partialeq(true)
.derive_eq(true)
.impl_debug(true)
.rustfmt_bindings(true)
.clang_arg("-DCIMGUI_DEFINE_ENUMS_AND_STRUCTS=1");
for e in whitelist.structs {
builder = builder.whitelist_type(format!("^{}", e));
}
for e in whitelist.enums {
builder = builder.whitelist_type(format!("^{}", e));
}
for e in whitelist.definitions {
builder = builder.whitelist_function(format!("^{}", e));
}
let bindings = builder
.generate()
.map_err(|_| format_err!("Failed to generate bindings"))?;
Ok(bindings)
}
20 changes: 20 additions & 0 deletions imgui-sys-bindgen/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
extern crate imgui_sys_bindgen;

use imgui_sys_bindgen::generate_bindings;
use std::env;

fn main() {
let cwd = env::current_dir().expect("Failed to read current directory");
let sys_path = cwd
.join("..")
.join("imgui-sys")
.canonicalize()
.expect("Failed to find imgui-sys directory");
let bindings = generate_bindings(&sys_path.join("third-party").join("cimgui"))
.expect("Failed to generate bindings");
let output_path = sys_path.join("src").join("bindings.rs");
bindings
.write_to_file(&output_path)
.expect("Failed to write bindings");
println!("Wrote bindings to {}", output_path.to_string_lossy());
}
2 changes: 1 addition & 1 deletion imgui-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ build = "build.rs"
travis-ci = { repository = "Gekkio/imgui-rs" }

[dependencies]
libc = "0.2"
bitflags = "1.0"
glium = { version = "0.25", default-features = false, optional = true }
gfx = { version = "0.18", optional = true }
libc = "0.2"

[build-dependencies]
cc = "1.0"
Loading

0 comments on commit 3ca1b7b

Please sign in to comment.