You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.6 KiB

//! Rust bindings and interop for GHOST.
//!
//! # Layout
//! ABI-compatable types and functions are all prefixed with `GHOST_` and are exported in the `c` module.
//! I've attempted to provide more Rust-idiomatic API variants as well, which have non-prefixed names.
//!
//! # Namespace polution and interface stablility
//! Eventually I think we should have *most* (if not all) C compatable types either reimplemented or aliased to non-prefixed Rust types.
//! At present though this is not the case, and prefixed names that can double as ergonomic Rust types are not aliased to them, so you'll have to use both often.
//! The reimplementation is undergoing, the aliasing not yet.
#![cfg_attr(nightly, feature(never_type))]
#![cfg_attr(nightly, feature(try_trait))]
#![allow(dead_code)]
#![allow(non_camel_case_types)]
#[cfg(nightly)] pub(crate) type PVoid = *const !;
#[cfg(not(nightly))] pub(crate) type PVoid = *const libc::c_void;
#[cfg(nightly)] pub(crate) type PVoidMut = *mut !;
#[cfg(not(nightly))] pub(crate) type PVoidMut = *mut libc::c_void;
mod private
{
pub trait Sealed{}
}
pub mod handle;
pub mod event;
pub mod types;
pub mod error;
pub mod api;
macro_rules! from_null {
($ptr:expr) => {
{
let ptr = $ptr;
if ptr.is_null() {
return Err($crate::error::GhostError(()))?;
} else {
ptr
}
}
};
(return $ptr:expr) => {
{
let ptr = $ptr;
if ptr.is_null() {
Err($crate::error::GhostError(()))
} else {
Ok(ptr)
}
}
}
}
macro_rules! debug {
($debug:expr; $prod:expr) => {
{
#[cfg(debug_assertions)] $debug;
#[cfg(not(debug_assertions))] $prod;
}
};
($debug:expr) => {
{
#[cfg(debug_assertions)] $debug
}
};
}
pub mod system;
pub mod c;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
unsafe {
let ptr = api::GHOST_CreateSystem();
assert!(!ptr.is_null());
}
}
macro_rules! static_assert {
($expression:expr $(, $message:literal)?) => {
const _: [u8; 1] = [0u8; (!!($expression)) as usize];
};
}
#[repr(C)]
enum DummyCEnum
{
One = 0,
Two,
Three,
}
// validate the dumb bitflags hack
static_assert!(std::mem::size_of::<types::GHOST_GLFlags>() == std::mem::size_of::<DummyCEnum>(),
"C enum is not of type `int`. Either that or #[repr(transparent)] is broken. Aborting.");
static_assert!(std::mem::align_of::<types::GHOST_GLFlags>() == std::mem::align_of::<DummyCEnum>(),
"C enum has unexpected alignment differing from type `int`. Either that or #[repr(transparent)] is broken. Aborting.");
// ..are there others?
}