/// Create a new type to represent a class. /// /// This is similar to an `@interface` declaration in Objective-C. /// /// It is useful for things like `objc2-foundation`, which needs to create /// interfaces to existing, externally defined classes like `NSString`, /// `NSURL` and so on, but can also be useful for users that have custom /// classes written in Objective-C that they want to access from Rust. /// /// /// # Specification /// /// The syntax is similar enough to Rust syntax that if you invoke the macro /// with parentheses (as opposed to curly brackets), [`rustfmt` will be able to /// format the contents][rustfmt-macros] (so e.g. as `extern_class!( ... );`). /// /// The macro creates an opaque struct containing the superclass (which means /// that auto traits are inherited from the superclass), and implements the /// following traits for it to allow easier usage as an Objective-C object: /// /// - [`RefEncode`][crate::RefEncode] /// - [`Message`][crate::Message] /// - [`Deref<Target = $superclass>`][core::ops::Deref] /// - [`ClassType`][crate::ClassType] /// - [`DowncastTarget`][$crate::DowncastTarget] /// - [`AsRef<$inheritance_chain>`][AsRef] /// - [`Borrow<$inheritance_chain>`][core::borrow::Borrow] /// /// If generics are specified, these will be placed in a [`PhantomData`]. /// /// [rustfmt-macros]: https://github.com/rust-lang/rustfmt/discussions/5437 /// [`PhantomData`]: core::marker::PhantomData /// /// /// ## Attributes /// /// You can add most normal attributes to the class, including `#[cfg(...)]`, /// `#[allow(...)]` and doc comments. /// /// Exceptions and special attributes are noted below. /// /// /// ### `#[unsafe(super(...))]` (required) /// /// Controls the [superclass][crate::ClassType::Super] and the rest of the /// inheritance chain. This attribute is required. /// /// Due to Rust trait limitations, specifying e.g. the superclass `NSData` /// would not give you the ability to convert via `AsRef` to `NSObject`. /// Therefore, you can optionally specify additional parts of the inheritance /// in this attribute. /// /// /// ### `#[thread_kind = ...]` (optional) /// /// Controls the [thread kind][crate::ClassType::ThreadKind], i.e. it can be /// set to [`MainThreadOnly`] if the object is only usable on the main thread. /// /// [`MainThreadOnly`]: crate::MainThreadOnly /// /// /// ### `#[name = "..."]` (optional) /// /// Controls the [name][crate::ClassType::NAME] of the class. /// /// If not specified, this will default to the struct name. /// /// /// ### `#[derive(...)]` /// /// This is overridden, and only works with [`PartialEq`], [`Eq`], [`Hash`] /// and [`Debug`]. /// /// [`Hash`]: std::hash::Hash /// [`Debug`]: std::fmt::Debug /// /// /// # #[cfg(not_available)] /// /// This is only supported for attributes that apply to the struct itself /// (i.e. not supported for attributes that apply to implementations, or any /// of the custom attributes). /// /// /// ### `#[repr(...)]` /// /// Not allowed (the macro uses this attribute internally). /// /// /// # Safety /// /// When writing `#[unsafe(super(...))]`, you must ensure that: /// 1. The first superclass is correct. /// 2. The thread kind is set to `MainThreadOnly` if the class can only be /// used from the main thread. /// /// /// # Examples /// /// Create a new type to represent the `NSFormatter` class (for demonstration, /// `objc2_foundation::NSFormatter` exist for exactly this purpose). /// /// ``` /// # #[cfg(not_available)] /// use objc2_foundation::{NSCoding, NSCopying, NSObjectProtocol}; /// # use objc2::runtime::NSObjectProtocol; /// use objc2::rc::Retained; /// use objc2::runtime::NSObject; /// use objc2::{extern_class, extern_conformance, msg_send, ClassType}; /// /// extern_class!( /// /// An example description, to show that doc comments work. /// // Specify the superclass, in this case `NSObject` /// #[unsafe(super(NSObject))] /// // We could specify that the class is only usable on the main thread. /// // #[thread_kind = MainThreadOnly]; /// // And specify the name of the class, if it differed from the struct. /// // #[name = "NSFormatter"]; /// // These derives use the superclass' implementation. /// #[derive(PartialEq, Eq, Hash, Debug)] /// pub struct NSFormatter; /// ); /// /// // Note: We have to specify the protocols for the superclasses as well, /// // since Rust doesn't do inheritance. /// extern_conformance!(unsafe impl NSObjectProtocol for NSFormatter {}); /// # #[cfg(not_available)] /// extern_conformance!(unsafe impl NSCopying for NSFormatter {}); /// # #[cfg(not_available)] /// extern_conformance!(unsafe impl NSCoding for NSFormatter {}); /// /// fn main() { /// // Provided by the implementation of `ClassType` /// let cls = NSFormatter::class(); /// /// // `NSFormatter` implements `Message`: /// let obj: Retained<NSFormatter> = unsafe { msg_send![cls, new] }; /// } /// ``` /// /// Represent the `NSDateFormatter` class, using the `NSFormatter` type we /// declared previously to specify as its superclass. /// /// ``` /// # #[cfg(not_available)] /// use objc2_foundation::{NSCoding, NSCopying, NSObjectProtocol}; /// # use objc2::runtime::NSObjectProtocol; /// use objc2::runtime::NSObject; /// use objc2::{extern_class, extern_conformance, ClassType}; /// # /// # extern_class!( /// # #[unsafe(super(NSObject))] /// # #[derive(PartialEq, Eq, Hash, Debug)] /// # pub struct NSFormatter; /// # ); /// /// extern_class!( /// // Specify the correct inheritance chain /// #[unsafe(super(NSFormatter, NSObject))] /// #[derive(PartialEq, Eq, Hash, Debug)] /// pub struct NSDateFormatter; /// ); /// /// // Similarly, we can specify the protocols that this implements here: /// extern_conformance!(unsafe impl NSObjectProtocol for NSDateFormatter {}); /// # #[cfg(not_available)] /// extern_conformance!(unsafe impl NSCopying for NSDateFormatter {}); /// # #[cfg(not_available)] /// extern_conformance!(unsafe impl NSCoding for NSDateFormatter {}); /// ``` /// /// See the source code of `objc2-foundation` for many more examples. #] #[]
macro_rules {
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
/java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58 // - #[unsafe(super($($superclasses:path),*))]
// - #[thread_kind = $thread_kind:path] // - #[name = $name:literal] // // As well as the following standard attributes: // - #[derive(Eq, PartialEq, Hash, Debug)] (only those four are supported) // - #[cfg(...)] // - #[cfg_attr(..., ...)] (only for standard attributes) // - #[doc(...)] // - #[deprecated(...)] // - #[allow/expect/warn/deny/forbid](java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20 (
// that[(.)`and[] not.
$(#[$($attrs:tt)*])*
$v:vis struct $class:ident;
) => {
$crate:_xtract_struct_attributes{
($(#[$($attrs)*])*)
c:_extern_class_inner
$,)java.lang.StringIndexOutOfBoundsException: Range [17, 18) out of bounds for length 17
$)
() // No generics
}
};
( // Generic version. Currently pretty ill supported.
$(# $)
$v:vis struct
$($generic:ident $(: $(?$bound_sized:ident)? $($bound:ident)?)? $( $)
$$?bound_sized? $$ound)))
>;
) => {
$ ($($efault?)
($(#[$($attrs)*])*)
($crate::__extern_class_inner)
($v) *)
($class)
($(
( }
($(java.lang.StringIndexOutOfBoundsException: Range [1, 2) out of bounds for length 1
($(m!_e{
)*)
}
};
}
#[doc(hidden)] # $:java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
!_extern_class_inner{
(
($v:vis)
($class:($($defaul:)?)
$$java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
(:java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
$$tt)+?java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
($($default:ty)?)
)+)?)
($($safety:tt*java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
($($($:+?java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
($($name:tt)*)
($tt*
($( (attr_struct*
java.lang.StringIndexOutOfBoundsException: Range [69, 29) out of bounds for length 29
($($($$?
) => { // Ensure that the type has the same layout as the superclass. // #[repr(transparent)] doesn't work because the superclass is a ZST. #[repr
$(::java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
_:c:m:<(* $generic),+)>,)?
__ crate_!{
($( u impl<$java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 80 // For diagnostics / rust-analyzer's sake, we choose a default // superclass so that we can continue compiling, even though,$)?:java.lang.StringIndexOutOfBoundsException: Range [76, 77) out of bounds for length 76
/ ' in // `__extern_class_check_super_unsafe` below.
(::)
} // Bind generics (and make them invariant).}
(_:c:_:(( generic+>)
}
$crate:
($($attr_impl)*/java.lang.StringIndexOutOfBoundsException: Index 98 out of bounds for length 98
(unsafe java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 22
(($$,))
($($superclass, $($superclasses,)*)java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
$crate::__extern_class_derives crate_!
$$))
(impl $(<
($class $ ;
java.lang.StringIndexOutOfBoundsException: Range [23, 12) out of bounds for length 26
}
// SAFETY: This maps `SomeClass<T, ...>` to a single `SomeClass<AnyObject, ...>` type and // implements `DowncastTarget` on that type. This is safe because the "base container" class
/ theandgenericis AnyObject // any Objective-C class instance.
$( }java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
$(<$$:_extern_class_map_anyobject!$generic),>? {}
$($attr_impl)* unsafeimpl $(<$($generic $(: $($bounds)+ + $crate::Message)?),*>)? $crate::ClassType typeSuper = $;
($($ fn class() -> &'staticlass)-'$:runtime:AnyClass java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
// See _ is for.
($crate::runtime::NSObject)
};
type ThreadKindl Selfcrate_::MainThreadOnlyDoesNotImplSendSync>:java.lang.StringIndexOutOfBoundsException: Index 103 out of bounds for length 103
($(dyn ($($thread_kind)+))?
// the kind
(<<Selfas $crate::($n*
}java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
const NAME: &'static $crate::__macro_helpers::str = $crate::__fallback_if_not_set! {
($( ()-&:{
($crate:&java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 34
;
#inlinejava.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21 fn$:_((s$?java.lang.StringIndexOutOfBoundsException: Range [76, 77) out of bounds for length 76 let=S ascrate:mV< c:>::; let _ = <Selfas $crate::__macro_helpers::MainThreadOnlyDoesNotImplSendSyncjava.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
($$:t)={
$crate::__class_inner!( #super.) `, [java.lang.StringIndexOutOfBoundsException: Range [71, 70) out of bounds for length 84
($(name*)
($crate::__"must specify the superclass #unsafe(super(.)]java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
}[java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 15
}
#[inline] fn as_super(&self) }java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
&._
}
const (:)* = java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
type __SubclassingType = Self;
}
$($java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
macro_rules_ java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
$($attr_impl)*
$crate$$:))
};
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
java.lang.StringIndexOutOfBoundsException: Range [14, 15) out of bounds for length 14 #[
java.lang.StringIndexOutOfBoundsException: Range [48, 49) out of bounds for length 48
(unsafe/java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
(safe $($java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 10
$:_:! "#[super(...)] must
);
}
( unsafeimpl$after_impl*c: () java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
$crate::__macro_helpers:=$ crate::
mustjava.lang.StringIndexOutOfBoundsException: Range [55, 54) out of bounds for length 68
)java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
};
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
#[doc #[ // `Val` ClassType hencemustjava.lang.StringIndexOutOfBoundsException: Range [78, 73) out of bounds for length 78
macro_rules _extern_class_map_anyobject
($t unsafe $($fter_impl)* $crate::Message for $($for)* {}
$crate:
}
}
// way, but `Deref` doesn't allow this). #[macro_export;whilewethe side
macro_rules! __extern_class_check_no_ivars
() => {};
($($ // TODO the a,we
$crate:m:(#ivars supported!;
};
}
#[doc(hidden)] #[macro_export]
(
(/ &<`- &T`>RetainedT> is
java.lang.StringIndexOutOfBoundsException: Range [40, 8) out of bounds for length 40
/RNSObject`' .
$superclasspath$(, $remaining_superclasses:path)*)
) => java.lang.StringIndexOutOfBoundsException: Range [28, 29) out of bounds for length 10 // SAFETY: // - The item is FFI-safe with `#[repr(C)]`. // - The encoding is taken from the inner item, and caller verifies // that it actually inherits said object. // - The rest of the struct's fields are ZSTs, so they don't influence // the layout. // // Be aware that very rarely, this implementation is wrong because the // class' instances do not have the encoding `Encoding::Object`. // impl $($after_impl)* $crate::__macro_helpers::AsRef<Self> for $($for)* { fn()>& java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39 } // `NSObject*`.
$($$crate::__extejava.lang.StringIndexOutOfBoundsException: Range [50, 49) out of bounds for length 52 unsafe java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
:$:
= <$superclass as ($*
}
// SAFETY: This is a newtype wrapper over `AnyObject` (we even ensure // that `AnyObject` is always last in our inheritance tree), so it is // always safe to reinterpret as that. // // That the object must work with standard memory management is // properly upheld by the fact that the superclass is required by // `ValidThreadKind` to implement `ClassType`, and hence must also bejava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
! _{
$($attr_impl)*
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
// SAFETY: An instance can always be _used_ in exactly the same way as
// way, but `Deref` doesn't allow this). // // Remember; while we (the Rust side) may intentionally be forgetting // which instance we're holding, the Objective-C side will remember, // and will always dispatch to the correct method implementations. // // TODO: If the object has a lifetime, we must keep that lifetime
// `Message::retain`, and that could possibly make it unsound to allow // non-`'static` here. // // `&NSMutableArray<T>` -> `&NSArray<T>` -> `Retained<NSArray<T>>` is // fine, but `&UserClass<'a>` -> `&NSObject` -> `Retained<NSObject>` / is not, and hence `&NSArray<UserClass<'a>>` -> `&NSObject` -> // `Retained<NSObject>` isn't either.
* impl $($after_impl)* $crate }= { type Target = $superclass;
$($attr_impljava.lang.StringIndexOutOfBoundsException: Range [20, 21) out of bounds for length 0 impl// #[inline] fn as_ref self
}
}
c:_!{
($superclass $(, $remaining_superclasses)*)
($($attr_impl)*)
(impl $($java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 9
($(()*java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42 fn as_refimpl(* // Triggers Deref coercion depending on return type
&*self
java.lang.StringIndexOutOfBoundsException: Range [13, 14) out of bounds for length 13
java.lang.StringIndexOutOfBoundsException: Range [9, 10) out of bounds for length 9
;
}
#[doc(hiddenl(mpl$$:)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
[java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 15
!_java.lang.StringIndexOutOfBoundsException: Range [47, 46) out of bounds for length 48 // Base case
{
()
(($ttr_impl:tt*)
(java.lang.StringIndexOutOfBoundsException: Range [0, 13) out of bounds for length 9
($($for:tt)*) fn as_ref($($self:tt)*) $as_ref:block)
} =$a*
// For each superclass
{
$p ( $:)*
$$:))
(impl $ & crate:macro_helpers:'>- :_:: java.lang.StringIndexOutOfBoundsException: Index 120 out of bounds for length 120
$$:tt) fn as_ref($java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 13
} =
$ $rate::_extern_class_derives! { impl $($after_impl)* $crate::__macro_helpers::AsRef<$superclass> for (($attr_impl)*java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28 #[inline] fn as_ref($($self)*) -> &$superclass $as_ref
}
// Borrow is correct, since subclasses behaves identical to the class // they inherit (message sending doesn't care). //
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
(
($$*java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
)*)
($($for)*) fn fn eq(&selfother Self)- :_: java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
};
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
/// Note: We intentionally don't add e.g. `T: PartialEq`, as generic objects /// are always comparable, hashable and debuggable, regardless of their /// generic parameters.
[(] #[macro_export]
macro_rulesjava.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6 // Base case
(
$$java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 27
(impl $(
($($for Eq
($,)*java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
) => {} (attr_impl)java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
// Debug
($($attr_impl:tt)*)
(impl $($after_impl $rate:_extern_class_derives! {
($($for:tt)*)
(
$( $)*
Debug
$($rest:tt)*
)
) => {
$($attr_impl)* #[automatically_derived]
$(after_impl) $rate:_macro_helpers:fmt:Debug for $$for)*java.lang.StringIndexOutOfBoundsException: Range [79, 80) out of bounds for length 79
(s :& crate:_::<_)- :_f:{ // Delegate to the superclass
$:_:::&_superclass)
}
}
$crate: $for:))
($($java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 16
(java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 10
(for*
($ (after_impl*crate:m: for $for*java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
}
};
// PartialEq
(
($($java.lang.StringIndexOutOfBoundsException: Range [0, 21) out of bounds for length 13
( $crat:_! java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
($($for:tt)*)
(
$(,)*
($for)
$($rest:tt)*
)
) => {
$($attr_impl)* #[automatically_derived$$:)java.lang.StringIndexOutOfBoundsException: Range [27, 28) out of bounds for length 27 impl $($java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 9
[] fn eq(&self, other: &Self) -> $crate::_java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 9 // Delegate to the superclass crate:__acro_helpers::PartialEq::(self__uperclass, &._superclass)
java.lang.StringIndexOutOfBoundsException: Range [13, 14) out of bounds for length 13
}
$crate::__extern_class_derives! {
$$))
(impl $($after_impl)*)
($($
($( crate:_! java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
java.lang.StringIndexOutOfBoundsException: Range [9, 10) out of bounds for length 9
};
// Eq
(
(}
(impl $($after_impl:tt)*)
((fort)*java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 9
()
Eq
$ java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
)
) => {
(attr_impl* #[automatically_derived]
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.9Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.