use objc::{
msg_send,
runtime::{Class, Protocol, Sel},
sel, sel_impl,
};
use crate::{
foundation::{NSString, UInt},
utils::to_bool,
};
use super::id;
pub trait INSObject {
fn new() -> Self;
fn to_id(self) -> id;
unsafe fn from_id(obj: id) -> Self;
fn description(&self) -> NSString;
fn debug_description(&self) -> NSString;
fn retain(&self) -> Self;
}
pub trait PNSObject {
fn m_new() -> Self
where
Self: Sized + FromId,
{
unsafe { Self::from_id(msg_send![Self::m_class(), new]) }
}
fn m_alloc() -> Self
where
Self: Sized + FromId,
{
unsafe { Self::from_id(msg_send![Self::m_class(), alloc]) }
}
fn m_initialize() {
unsafe { msg_send![Self::m_class(), initialize] }
}
fn m_class<'a>() -> &'a Class;
fn ip_superclass<'a>() -> Option<&'a Class> {
Self::m_class().superclass()
}
fn m_is_equal(&self, object: &Self) -> bool {
unsafe { to_bool(msg_send![self.m_self(), isEqual: object]) }
}
fn p_hash(&self) -> UInt {
unsafe { msg_send![self.m_self(), hash] }
}
fn m_self(&self) -> id;
fn m_is_kind_of_class(&self, class: Class) -> bool {
unsafe { to_bool(msg_send![self.m_self(), isKindOfClass: class]) }
}
fn m_is_member_of_class(&self, class: Class) -> bool {
unsafe { to_bool(msg_send![self.m_self(), isMemberOfClass: class]) }
}
fn m_responds_to_selector(&self, selector: Sel) -> bool {
unsafe { to_bool(msg_send![self.m_self(), respondsToSelector: selector]) }
}
fn m_conforms_to_protocol(&self, protocol: Protocol) -> bool {
unsafe { to_bool(msg_send![self.m_self(), conformsToProtocol: protocol]) }
}
fn p_description(&self) -> NSString {
unsafe { NSString::from_id(msg_send![self.m_self(), description]) }
}
fn p_debug_description(&self) -> NSString {
unsafe { NSString::from_id(msg_send![self.m_self(), debugDescription]) }
}
fn m_perform_selector(&self, selector: Sel) -> id {
unsafe { msg_send![self.m_self(), performSelector: selector] }
}
fn m_perform_selector_with_object(&self, selector: Sel, with_object: id) -> id {
unsafe { msg_send![self.m_self(), performSelector: selector withObject: with_object] }
}
fn m_is_proxy(&self) -> bool {
unsafe { to_bool(msg_send![self.m_self(), isProxy]) }
}
}
pub trait FromId: ToId {
unsafe fn from_id(ptr: id) -> Self;
}
pub trait ToId {
fn to_id(self) -> id;
}