Skip to content

Commit

Permalink
Implement comparison traits for Bool
Browse files Browse the repository at this point in the history
These are useful in many cases, and just an annoyance at this point that
we don't have it.
  • Loading branch information
madsmtm committed Jan 21, 2025
1 parent 04077a2 commit 5054c61
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 94 deletions.
7 changes: 1 addition & 6 deletions crates/header-translator/src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2399,12 +2399,7 @@ impl Stmt {
if *is_union || fields.iter().any(|(_, _, field)| field.contains_union()) {
writeln!(f, "#[derive(Clone, Copy)]")?;
} else {
// HACK to make Bool in structs work.
if fields.iter().any(|(_, _, field)| field.is_objc_bool()) {
writeln!(f, "#[derive(Clone, Copy, Debug)]")?;
} else {
writeln!(f, "#[derive(Clone, Copy, Debug, PartialEq)]")?;
}
writeln!(f, "#[derive(Clone, Copy, Debug, PartialEq)]")?;
}
if *is_union {
writeln!(f, "pub union {} {{", id.name)?;
Expand Down
2 changes: 2 additions & 0 deletions crates/objc2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
insufficient).
* Added `#[unsafe(method_family = ...)]` attribute in `extern_methods!` and
`extern_protocol!`, to allow overriding the inferred method family.
* Added `PartialEq`, `Eq`, `Hash`, `PartialOrd` and `Ord` implementations for
`Bool`.

### Changed
* **BREAKING**: Renamed `declare_class!` to `define_class!`, and changed the
Expand Down
51 changes: 44 additions & 7 deletions crates/objc2/src/runtime/bool.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![allow(clippy::upper_case_acronyms)]
use core::fmt;
use core::{fmt, hash};

use crate::encode::{Encode, Encoding, RefEncode};

Expand Down Expand Up @@ -86,17 +86,13 @@ mod inner {
/// around `bool` instead.
///
/// Note that this is able to contain more states than `bool` on some
/// platforms, but these cases should not be relied on!
/// platforms, but these cases should not be relied on! The comparison traits
/// `PartialEq`, `PartialOrd` etc. will completely ignore these states.
///
/// See also the [corresponding documentation entry][docs].
///
/// [docs]: https://developer.apple.com/documentation/objectivec/bool?language=objc
#[repr(transparent)]
// We don't implement comparison traits because they could be implemented with
// two slightly different semantics:
// - `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)]
pub struct Bool {
value: inner::BOOL,
Expand Down Expand Up @@ -181,6 +177,38 @@ impl fmt::Debug for Bool {
}
}

// Implement comparison traits by first converting to a boolean.

impl PartialEq for Bool {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.as_bool() == other.as_bool()
}
}

impl Eq for Bool {}

impl hash::Hash for Bool {
#[inline]
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.as_bool().hash(state);
}
}

impl PartialOrd for Bool {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other))
}
}

impl Ord for Bool {
#[inline]
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.as_bool().cmp(&other.as_bool())
}
}

trait Helper {
const __ENCODING: Encoding;
}
Expand Down Expand Up @@ -278,6 +306,11 @@ mod tests {

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

assert_eq!(Bool::new(true), Bool::new(true));
assert_eq!(Bool::new(false), Bool::new(false));

assert!(Bool::new(false) < Bool::new(true));
}

#[test]
Expand All @@ -294,5 +327,9 @@ mod tests {
assert!(b.is_true());
assert!(!b.is_false());
assert_eq!(b.as_raw(), 42);

// PartialEq ignores extra data
assert_eq!(b, Bool::new(true));
assert_ne!(b, Bool::new(false));
}
}
6 changes: 0 additions & 6 deletions framework-crates/objc2-avf-audio/translation-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ class.AVAudioEngine.methods."renderOffline:toBuffer:error:".skipped = true
# Non-null error return
class.AVAudioSequencer.methods."dataWithSMPTEResolution:error:".skipped = true

# tries to derive with `PartialEq` which fails because of `Bool` fields
struct.AVAudioVoiceProcessingOtherAudioDuckingConfiguration.skipped = true
typedef.AVAudioVoiceProcessingOtherAudioDuckingConfiguration.skipped = true
class.AVAudioInputNode.methods.voiceProcessingOtherAudioDuckingConfiguration.skipped = true
class.AVAudioInputNode.methods."setVoiceProcessingOtherAudioDuckingConfiguration:".skipped = true

# Needs AppKit or UIKit
class.AVAudioUnitComponent.methods.icon.skipped = true

Expand Down

This file was deleted.

5 changes: 0 additions & 5 deletions framework-crates/objc2-game-controller/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,10 @@ extern crate alloc;
#[cfg(feature = "std")]
extern crate std;

#[cfg(feature = "GCExtendedGamepadSnapshot")]
mod extended_gamepad_snapshot;
mod generated;
#[cfg(feature = "GCInputNames")]
mod input_names;

#[cfg(feature = "GCExtendedGamepadSnapshot")]
#[allow(deprecated)]
pub use self::extended_gamepad_snapshot::GCExtendedGamepadSnapshotData;
#[allow(unused_imports, unreachable_pub)]
pub use self::generated::*;
#[cfg(feature = "GCInputNames")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ static.GCInputRightPaddle.skipped = true
# Uses GCInputButtonName
fn.GCInputArcadeButtonName.skipped = true

# tries to derive with `PartialEq` which fails because of `Bool` fields; manually define for now
struct.GCExtendedGamepadSnapshotData.skipped = true

# Needs `CHHapticEngine` from the `CoreHaptics` framework
class.GCDeviceHaptics.methods."createEngineWithLocality:".skipped = true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ visionos = "1.0"
# Defined in both MPSCore.MPSImage and MPSCore.MPSNDArray
typedef.MPSImageBatch.skipped = true

# tries to derive with `PartialEq` which fails because of `Bool` fields
# struct.MPSImageHistogramInfo.skipped = true

# Has a union field, but we'd rather have it as just a struct
struct._MPSPackedFloat3.skipped = true
typedef.MPSPackedFloat3.skipped = true
Expand Down

0 comments on commit 5054c61

Please sign in to comment.