Right now we're just using type aliases - instead, we should generate newtypes with the appropriate traits and constants. See also how Swift does it.
EDIT: I think the output should be something like this (depending on the naming scheme, so until that the variant/method names might be longer):
-
NS_OPTIONS (example: NSSortOptions):
bitflags! {
#[repr(transparent)]
#[derive(Default)]
pub struct NSSortOptions: NSUInteger {
#[doc(alias = "NSSortConcurrent")]
const CONCURRENT = 1 << 0;
#[doc(alias = "NSSortStable")]
const STABLE = 1 << 4;
}
}
// Or perhaps we do something custom instead of `bitflags`?
// Not sure if we want all the traits and helper functions it exposes?
unsafe impl Encode for NSSortOptions { ... }
unsafe impl RefEncode for NSSortOptions { ... }
-
NS_ENUM (example: NSDecodingFailurePolicy):
// Cannot be a Rust `enum`, since that assumes that the enum is exhaustive
// ABI-wise, even with `#[non_exhaustive]`.
//
// See https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=3a19fcb4267d6fdb0d26b0c9defd946a
#[repr(transparent)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSDecodingFailurePolicy(NSInteger);
unsafe impl Encode for NSDecodingFailurePolicy { ... }
unsafe impl RefEncode for NSDecodingFailurePolicy { ... }
impl NSDecodingFailurePolicy {
pub fn as_raw(self) -> NSInteger { ... }
pub fn from_raw(raw: NSInteger) -> Option<Self> { ... }
pub unsafe fn from_raw_unchecked(raw: NSInteger) -> Self { ... }
#[doc(alias = "NSDecodingFailurePolicyRaiseException")]
pub const RAISE_EXCEPTION: Self = Self(0 as NSInteger);
#[doc(alias = "NSDecodingFailurePolicySetErrorAndReturn")]
pub const SET_ERROR_AND_RETURN: Self = Self(1 as NSInteger);
}
impl fmt::Debug for NSDecodingFailurePolicy { ... }
// Same as `as_raw`
impl From<NSDecodingFailurePolicy> for NSInteger { ... }
// Same as `from_raw`
impl TryFrom<NSInteger> for NSDecodingFailurePolicy { ... }
-
NS_CLOSED_ENUM (example: NSComparisonResult):
#[repr(isize)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
enum NSComparisonResult {
NSOrderedAscending = -1,
NSOrderedSame = 0,
NSOrderedDescending = 1,
}
unsafe impl Encode for NSComparisonResult { ... }
unsafe impl RefEncode for NSComparisonResult { ... }
-
NS_TYPED_ENUM (example: NSStringEncodingDetectionOptionsKey):
#[repr(C)]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct NSStringEncodingDetectionOptionsKey(NSString);
unsafe impl RefEncode for NSStringEncodingDetectionOptionsKey { ... }
unsafe impl Message for NSStringEncodingDetectionOptionsKey { ... }
impl NSStringEncodingDetectionOptionsKey {
pub fn as_raw(&self) -> &NSString { ... }
pub fn into_raw(this: Id<Self>) -> Id<NSString> { ... }
pub unsafe fn from_raw_unchecked(raw: &NSString) -> &Self { ... }
pub unsafe fn from_raw_id_unchecked(raw: Id<NSString>) -> Id<Self> { ... }
}
// Delegates to `NSString`
impl fmt::Display for NSStringEncodingDetectionOptionsKey { ... }
// + AsRef, Borrow and From implementations
// Constants
impl NSStringEncodingDetectionOptionsKey {
#[doc(alias = "NSStringEncodingDetectionSuggestedEncodingsKey")]
pub fn suggested_encodings_key() -> &'static Self { ... }
}
impl NSStringEncodingDetectionOptionsKey {
#[doc(alias = "NSStringEncodingDetectionDisallowedEncodingsKey")]
pub fn disallowed_encodings_key() -> &'static Self { ... }
}
// ...
-
NS_TYPED_EXTENSIBLE_ENUM (example: NSExceptionName):
#[repr(C)]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct NSExceptionName(pub(crate) NSString);
unsafe impl RefEncode for NSExceptionName { ... }
unsafe impl Message for NSExceptionName { ... }
impl NSExceptionName {
pub fn as_raw(&self) -> &NSString { ... }
pub fn into_raw(this: Id<Self>) -> Id<NSString> { ... }
pub fn from_raw(raw: &NSString) -> &Self { ... }
pub fn from_raw_id(raw: Id<NSString>) -> Id<Self> { ... }
}
// Delegates to `NSString`
impl fmt::Display for NSExceptionName { ... }
// + AsRef, Borrow and From implementations
// Constants (may be spread across frameworks)
impl NSExceptionName {
#[doc(alias = "NSGenericException")]
pub fn generic_exception() -> &'static Self { ... }
}
impl NSExceptionName {
#[doc(alias = "NSRangeException")]
pub fn range_exception() -> &'static Self { ... }
}
// ...
-
NS_ERROR_ENUM with typedef (example: MTLIOError + MTLIOErrorDomain):
-
NS_ERROR_ENUM without typedef (example: NSURLErrorDomain + related URL errors):
-
Anonymous enum (example: Memory Allocation Options):
const NSScannedOption: NSUInteger = 1 << 0;
const NSCollectorDisabledOption: NSUInteger = 1 << 1;
// Note: A bit unsure of the type here, maybe we just want to always use `NSInteger` like Swift does?
Right now we're just using type aliases - instead, we should generate newtypes with the appropriate traits and constants. See also how Swift does it.
EDIT: I think the output should be something like this (depending on the naming scheme, so until that the variant/method names might be longer):
NS_OPTIONS(example:NSSortOptions):NS_ENUM(example:NSDecodingFailurePolicy):NS_CLOSED_ENUM(example:NSComparisonResult):NS_TYPED_ENUM(example:NSStringEncodingDetectionOptionsKey):NS_TYPED_EXTENSIBLE_ENUM(example:NSExceptionName):NS_ERROR_ENUMwith typedef (example:MTLIOError+MTLIOErrorDomain):NS_ERROR_ENUMwithout typedef (example:NSURLErrorDomain+ related URL errors):Anonymous enum (example: Memory Allocation Options):