pub use objective_rust_macros::*;
#[cfg(not(target_os = "macos"))]
compile_error!("objective-rust only supports macOS");
#[repr(transparent)]
pub struct ObjcBool(std::ffi::c_char);
impl ObjcBool {
pub const TRUE: Self = Self(1);
pub const FALSE: Self = Self(0);
pub const YES: Self = Self::TRUE;
pub const NO: Self = Self::FALSE;
}
impl From<bool> for ObjcBool {
fn from(value: bool) -> Self {
match value {
true => Self::TRUE,
false => Self::FALSE,
}
}
}
impl From<ObjcBool> for bool {
fn from(value: ObjcBool) -> bool {
match value.0 {
1 => true,
0 => false,
_ => unreachable!(),
}
}
}
pub mod ffi {
use std::{ffi::CString, ptr::NonNull};
type Ptr = NonNull<()>;
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct Class(Ptr);
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct Instance(Ptr);
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct Implementation(Ptr);
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct Selector(Ptr);
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct Method(Ptr);
pub fn get_class(name: &str) -> Option<Class> {
let name = CString::new(name).ok()?;
let ptr = unsafe { objc_getClass(name.as_ptr()) };
Some(Class(Ptr::new(ptr)?))
}
pub fn get_metaclass(name: &str) -> Option<Class> {
let name = CString::new(name).ok()?;
let ptr = unsafe { objc_getMetaClass(name.as_ptr()) };
Some(Class(Ptr::new(ptr)?))
}
pub fn get_selector(name: &str) -> Option<Selector> {
let name = CString::new(name).ok()?;
let ptr = unsafe { sel_getUid(name.as_ptr()) };
Some(Selector(Ptr::new(ptr)?))
}
#[inline(always)]
pub fn get_method_impl(class: Class, method: Selector) -> Option<Implementation> {
let ptr = unsafe { class_getMethodImplementation(class, method) };
Some(Implementation(Ptr::new(ptr)?))
}
#[link(name = "objc")]
extern "C" {
fn class_getMethodImplementation(cls: Class, name: Selector) -> *mut ();
fn objc_getClass(name: *const i8) -> *mut ();
fn objc_getMetaClass(name: *const i8) -> *mut ();
fn sel_getUid(name: *const i8) -> *mut ();
}
}