#[cfg(feature = "NSObjCRuntime")]
use core::cmp::Ordering;
use core::fmt;
use core::hash;
use core::panic::{RefUnwindSafe, UnwindSafe};
use objc2::encode::Encoding;
use objc2::msg_send;
use objc2::rc::Retained;
use objc2::runtime::NSObject;
use crate::util;
use crate::NSNumber;
impl UnwindSafe for NSNumber {}
impl RefUnwindSafe for NSNumber {}
macro_rules! def_new_fn {
{$(
$(#[$($m:meta)*])*
($fn_name:ident($fn_inp:ty); $method_name:ident),
)*} => {$(
$(#[$($m)*])*
pub fn $fn_name(val: $fn_inp) -> Retained<Self> {
Self::$method_name(val as _)
}
)*}
}
impl NSNumber {
def_new_fn! {
(new_bool(bool); numberWithBool),
(new_i8(i8); numberWithChar),
(new_u8(u8); numberWithUnsignedChar),
(new_i16(i16); numberWithShort),
(new_u16(u16); numberWithUnsignedShort),
(new_i32(i32); numberWithInt),
(new_u32(u32); numberWithUnsignedInt),
(new_i64(i64); numberWithLongLong),
(new_u64(u64); numberWithUnsignedLongLong),
(new_isize(isize); numberWithInteger),
(new_usize(usize); numberWithUnsignedInteger),
(new_f32(f32); numberWithFloat),
(new_f64(f64); numberWithDouble),
}
#[inline]
#[cfg(all(feature = "objc2-core-foundation", feature = "NSGeometry"))]
pub fn new_cgfloat(val: objc2_core_foundation::CGFloat) -> Retained<Self> {
#[cfg(target_pointer_width = "64")]
{
Self::new_f64(val)
}
#[cfg(not(target_pointer_width = "64"))]
{
Self::new_f32(val)
}
}
}
macro_rules! def_get_fn {
{$(
$(#[$($m:meta)*])*
($fn_name:ident -> $fn_ret:ty; $method_name:ident),
)*} => {$(
$(#[$($m)*])*
pub fn $fn_name(&self) -> $fn_ret {
self.$method_name() as _
}
)*}
}
impl NSNumber {
def_get_fn! {
(as_bool -> bool; boolValue),
(as_i8 -> i8; charValue),
(as_u8 -> u8; unsignedCharValue),
(as_i16 -> i16; shortValue),
(as_u16 -> u16; unsignedShortValue),
(as_i32 -> i32; intValue),
(as_u32 -> u32; unsignedIntValue),
(as_i64 -> i64; longLongValue),
(as_u64 -> u64; unsignedLongLongValue),
(as_isize -> isize; integerValue),
(as_usize -> usize; unsignedIntegerValue),
(as_f32 -> f32; floatValue),
(as_f64 -> f64; doubleValue),
}
#[inline]
#[cfg(all(feature = "objc2-core-foundation", feature = "NSGeometry"))]
pub fn as_cgfloat(&self) -> objc2_core_foundation::CGFloat {
#[cfg(target_pointer_width = "64")]
{
self.as_f64()
}
#[cfg(not(target_pointer_width = "64"))]
{
self.as_f32()
}
}
pub fn encoding(&self) -> Encoding {
let enc = (**self)
.encoding()
.expect("NSNumber must have an encoding!");
match enc {
"c" => Encoding::Char,
"C" => Encoding::UChar,
"s" => Encoding::Short,
"S" => Encoding::UShort,
"i" => Encoding::Int,
"I" => Encoding::UInt,
"l" => Encoding::Long,
"L" => Encoding::ULong,
"q" => Encoding::LongLong,
"Q" => Encoding::ULongLong,
"f" => Encoding::Float,
"d" => Encoding::Double,
_ => unreachable!("invalid encoding for NSNumber"),
}
}
}
impl hash::Hash for NSNumber {
#[inline]
fn hash<H: hash::Hasher>(&self, state: &mut H) {
(**self).hash(state);
}
}
impl PartialEq for NSNumber {
#[doc(alias = "isEqualToNumber:")]
fn eq(&self, other: &Self) -> bool {
self.isEqualToNumber(other)
}
}
impl Eq for NSNumber {}
#[cfg(feature = "NSObjCRuntime")]
impl PartialOrd for NSNumber {
#[doc(alias = "compare:")]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[cfg(feature = "NSObjCRuntime")]
impl Ord for NSNumber {
#[doc(alias = "compare:")]
fn cmp(&self, other: &Self) -> Ordering {
self.compare(other).into()
}
}
impl fmt::Display for NSNumber {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let string: Retained<NSObject> = unsafe { msg_send![self, stringValue] };
unsafe { util::display_string(&string, f) }
}
}
impl fmt::Debug for NSNumber {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&***self, f)
}
}