macro_rules! __msg_send_parse {
{
()
()
($selector:ident $(,)?)
($($error_data:tt)*)
($($data:tt)*)
($out_macro:path)
$($macro_args:tt)*
} => {
__msg_send_parse! {
($selector)
()
()
($($error_data)*)
($($data)*)
($out_macro)
$($macro_args)*
}
};
{
($($selector_output:tt)*)
($($argument_output:tt)*)
()
($($error_data:tt)*)
($($data:tt)*)
($out_macro:path)
$($macro_args:tt)*
} => ({
$out_macro! {
$($macro_args)*
($($data)*)
($($selector_output)*)
($($argument_output)*)
}
});
{
($($selector_output:tt)*)
($($argument_output:tt)*)
($selector:ident: _ $(,)?)
($($error_data:tt)*)
($($data:tt)*)
($out_macro:path)
$($macro_args:tt)*
} => {
__msg_send_parse! {
($($selector_output)* $selector:)
($($argument_output)*)
()
($($error_data)*)
($($error_data)*)
($out_macro)
$($macro_args)*
}
};
{
($($selector_output:tt)*)
($($argument_output:tt)*)
($selector:ident : $argument:expr $(, $($rest:tt)*)?)
($($error_data:tt)*)
($($data:tt)*)
($out_macro:path)
$($macro_args:tt)*
} => {
__msg_send_parse! {
($($selector_output)* $selector:)
($($argument_output)* $argument,)
($($($rest)*)?)
($($error_data)*)
($($data)*)
($out_macro)
$($macro_args)*
}
};
{
()
()
($($selector:ident : $argument:expr)*)
($($error_data:tt)*)
($($data:tt)*)
($out_macro:path)
$($macro_args:tt)*
} => {{
__msg_send_parse! {
()
()
($($selector : $argument),*)
($($error_data)*)
($($data)*)
($out_macro)
$($macro_args)*
}
}};
}
macro_rules! msg_send {
[$obj:expr, $($selector_and_arguments:tt)+] => {
__msg_send_parse! {
()
()
($($selector_and_arguments)+)
(MsgSendError::send_message_error)
(MsgSend::send_message)
(objc2::__msg_send_helper)
($obj)
() }
};
}
macro_rules! obj_alloc {
($class_name: ident, $($init: tt)*) => {
{
let class = class!($class_name);
let mut obj: *mut Object = msg_send![class, alloc];
obj = msg_send![obj, $($init)*];
Retained::from_raw(obj).unwrap_unchecked()
}
};
}
macro_rules! obj_from {
($class_name: ident, $($init: tt)*) => {
{
let class = class!($class_name);
let obj: *mut Object = msg_send![class, $($init)*];
Retained::from_raw(obj).unwrap_unchecked()
}
};
}
pub(crate) use __msg_send_parse;
pub(crate) use msg_send;
pub(crate) use obj_alloc;
pub(crate) use obj_from;
use objc2::__framework_prelude::NSUInteger;
use std::ffi::c_char;
use objc2::runtime::{AnyObject, Bool};
pub type BOOL = Bool;
pub const NO: Bool = Bool::NO;
pub type Object = AnyObject;
pub fn ns_string_to_string(obj: &Object) -> &str {
let data: *const c_char = unsafe { msg_send![obj, UTF8String] };
let len: NSUInteger = unsafe { msg_send![obj, length] };
let slice = unsafe { std::slice::from_raw_parts(data as *const u8, len as usize) };
unsafe { std::str::from_utf8_unchecked(slice) }
}