Skip to content

Commit

Permalink
Add Bool::as_bool
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Jan 6, 2022
1 parent fd5ce60 commit ec2b90b
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 17 deletions.
4 changes: 2 additions & 2 deletions objc2-foundation/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub unsafe trait INSObject: Message {

fn is_equal<T: INSObject>(&self, other: &T) -> bool {
let result: Bool = unsafe { msg_send![self, isEqual: other] };
result.is_true()
result.as_bool()
}

fn description(&self) -> Id<NSString, Shared> {
Expand All @@ -30,7 +30,7 @@ pub unsafe trait INSObject: Message {

fn is_kind_of(&self, cls: &Class) -> bool {
let result: Bool = unsafe { msg_send![self, isKindOfClass: cls] };
result.is_true()
result.as_bool()
}
}

Expand Down
28 changes: 22 additions & 6 deletions objc2/src/bool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use core::fmt;
/// The Objective-C `BOOL` type.
///
/// This is a thin wrapper-type over [`objc_sys::BOOL`]. It is intended that
/// you convert this into a Rust [`bool`] with the [`Bool::is_false`] or
/// [`Bool::is_true`] methods as soon as possible.
/// you convert this into a Rust [`bool`] with the [`Bool::as_bool`] method as
/// soon as possible.
///
/// This is FFI-safe and can be used in directly with
/// [`msg_send!`][`crate::msg_send`].
Expand All @@ -20,12 +20,12 @@ use core::fmt;
/// use objc2::runtime::{Object, Bool};
/// let ns_value: *mut Object = unsafe { msg_send![class!(NSValue), initWithBool: Bool::YES] };
/// let rtn: Bool = unsafe { msg_send![ns_value, boolValue] };
/// assert!(rtn.is_true());
/// assert!(rtn.as_bool());
/// ```
#[repr(transparent)]
// We don't implement comparison traits because they could be implemented with
// two slightly different semantics:
// - `self.is_true().cmp(other.is_true())`
// - `self.as_bool().cmp(other.as_bool())`
// - `self.value.cmp(other.value)`
// And it is not immediately clear for users which one was chosen.
#[derive(Copy, Clone, Default)]
Expand Down Expand Up @@ -63,6 +63,8 @@ impl Bool {
}

/// Returns `true` if `self` is [`NO`][`Self::NO`].
///
/// You should prefer using [`as_bool`][`Self::as_bool`].
#[inline]
pub const fn is_false(self) -> bool {
// Always compare with 0
Expand All @@ -71,12 +73,20 @@ impl Bool {
}

/// Returns `true` if `self` is the opposite of [`NO`][`Self::NO`].
///
/// You should prefer using [`as_bool`][`Self::as_bool`].
#[inline]
pub const fn is_true(self) -> bool {
// Always compare with 0
// This is what happens when using `if` in C.
self.value as u8 != 0
}

/// Converts this into the [`bool`] equivalent.
#[inline]
pub const fn as_bool(self) -> bool {
self.is_true()
}
}

impl From<bool> for Bool {
Expand All @@ -89,13 +99,13 @@ impl From<bool> for Bool {
impl From<Bool> for bool {
#[inline]
fn from(b: Bool) -> bool {
b.is_true()
b.as_bool()
}
}

impl fmt::Debug for Bool {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(if self.is_true() { "YES" } else { "NO" })
f.write_str(if self.as_bool() { "YES" } else { "NO" })
}
}

Expand Down Expand Up @@ -125,12 +135,14 @@ mod tests {
#[test]
fn test_basic() {
let b = Bool::new(true);
assert!(b.as_bool());
assert!(b.is_true());
assert!(!b.is_false());
assert!(bool::from(b));
assert_eq!(b.as_raw() as usize, 1);

let b = Bool::new(false);
assert!(!b.as_bool());
assert!(!b.is_true());
assert!(b.is_false());
assert!(!bool::from(b));
Expand All @@ -140,19 +152,23 @@ mod tests {
#[test]
fn test_associated_constants() {
let b = Bool::YES;
assert!(b.as_bool());
assert!(b.is_true());
assert_eq!(b.as_raw() as usize, 1);

let b = Bool::NO;
assert!(!b.as_bool());
assert!(b.is_false());
assert_eq!(b.as_raw() as usize, 0);
}

#[test]
fn test_impls() {
let b: Bool = Default::default();
assert!(!b.as_bool());
assert!(b.is_false());

assert!(Bool::from(true).as_bool());
assert!(Bool::from(true).is_true());
assert!(Bool::from(false).is_false());

Expand Down
8 changes: 4 additions & 4 deletions objc2/src/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ impl ClassDecl {
types.as_ptr(),
)
});
assert!(success.is_true(), "Failed to add method {:?}", sel);
assert!(success.as_bool(), "Failed to add method {:?}", sel);
}

/// Adds a class method with the given name and implementation.
Expand Down Expand Up @@ -253,7 +253,7 @@ impl ClassDecl {
types.as_ptr(),
)
});
assert!(success.is_true(), "Failed to add class method {:?}", sel);
assert!(success.as_bool(), "Failed to add class method {:?}", sel);
}

/// Adds an ivar with type `T` and the provided name.
Expand All @@ -275,7 +275,7 @@ impl ClassDecl {
encoding.as_ptr(),
)
});
assert!(success.is_true(), "Failed to add ivar {}", name);
assert!(success.as_bool(), "Failed to add ivar {}", name);
}

/// Adds the given protocol to self.
Expand All @@ -285,7 +285,7 @@ impl ClassDecl {
/// If the protocol wasn't successfully added.
pub fn add_protocol(&mut self, proto: &Protocol) {
let success = unsafe { ffi::class_addProtocol(self.cls as _, proto.as_ptr()) };
let success = Bool::from_raw(success).is_true();
let success = Bool::from_raw(success).as_bool();
assert!(success, "Failed to add protocol {:?}", proto);
}

Expand Down
2 changes: 1 addition & 1 deletion objc2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
//! // Usage
//! let hash: NSUInteger = unsafe { msg_send![obj, hash] };
//! let is_kind: Bool = unsafe { msg_send![obj, isKindOfClass: cls] };
//! assert!(is_kind.is_true());
//! assert!(is_kind.as_bool());
//! ```
//!
//! Note that this very simple example contains **a lot** of `unsafe` (which
Expand Down
8 changes: 4 additions & 4 deletions objc2/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ impl Class {

#[allow(unused)]
fn is_metaclass(&self) -> bool {
unsafe { Bool::from_raw(ffi::class_isMetaClass(self.as_ptr())).is_true() }
unsafe { Bool::from_raw(ffi::class_isMetaClass(self.as_ptr())).as_bool() }
}

/// Returns the size of instances of self.
Expand Down Expand Up @@ -378,7 +378,7 @@ impl Class {
/// Checks whether this class conforms to the specified protocol.
pub fn conforms_to(&self, proto: &Protocol) -> bool {
unsafe {
Bool::from_raw(ffi::class_conformsToProtocol(self.as_ptr(), proto.as_ptr())).is_true()
Bool::from_raw(ffi::class_conformsToProtocol(self.as_ptr(), proto.as_ptr())).as_bool()
}
}

Expand Down Expand Up @@ -478,7 +478,7 @@ impl Protocol {
self.as_ptr(),
proto.as_ptr(),
))
.is_true()
.as_bool()
}
}

Expand All @@ -493,7 +493,7 @@ impl PartialEq for Protocol {
/// Check whether the protocols are equal, or conform to each other.
#[inline]
fn eq(&self, other: &Protocol) -> bool {
unsafe { Bool::from_raw(ffi::protocol_isEqual(self.as_ptr(), other.as_ptr())).is_true() }
unsafe { Bool::from_raw(ffi::protocol_isEqual(self.as_ptr(), other.as_ptr())).as_bool() }
}
}

Expand Down

0 comments on commit ec2b90b

Please sign in to comment.