-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
139 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,70 @@ | ||
use objc2::rc::{Id, Owned, Ownership}; | ||
use objc2::{msg_send_id, Message}; | ||
use crate::common::*; | ||
|
||
pub unsafe trait NSCopying: Message { | ||
/// Indicates whether the type is mutable or immutable. | ||
/// | ||
/// This can be [`Owned`] if and only if `copy` creates a new instance, | ||
/// see the following example: | ||
/// | ||
/// ```ignore | ||
/// let x: Id<MyObject, _> = MyObject::new(); | ||
/// // This is valid only if `y` is a new instance. Otherwise `x` and `y` | ||
/// // would be able to create aliasing mutable references! | ||
/// let y: Id<MyObject, Owned> = x.copy(); | ||
/// ``` | ||
/// | ||
/// Note that for the same reason, you should be careful when defining | ||
/// `new` methods on your object; e.g. immutable types like [`NSString`] | ||
/// don't return `Id<NSString, Owned>`, because that would allow this | ||
/// trait to create an aliasing `Id<NSString, Shared>` (since sending the | ||
/// `copy` message (and others) does not create a new instance, but | ||
/// instead just retains the instance). | ||
/// | ||
/// [`NSString`]: crate::Foundation::NSString | ||
type Ownership: Ownership; | ||
mod private { | ||
use super::*; | ||
use objc2::class::{ | ||
Immutable, ImmutableWithMutableSubclass, InteriorMutable, MainThreadOnly, Mutable, Unknown, | ||
}; | ||
|
||
/// The output type. | ||
/// | ||
/// This is usually `Self`, but e.g. `NSMutableString` returns `NSString`. | ||
type Output: Message; | ||
|
||
fn copy(&self) -> Id<Self::Output, Self::Ownership> { | ||
unsafe { msg_send_id![self, copy] } | ||
pub trait Copyhelper<T: ?Sized> { | ||
type CopyOutput: ?Sized + Message; | ||
type MutableCopyOutput: ?Sized + Message; | ||
} | ||
impl<T: ?Sized + Message> Copyhelper<T> for Unknown { | ||
type CopyOutput = T; | ||
type MutableCopyOutput = T; | ||
} | ||
impl<T: ?Sized + Message> Copyhelper<T> for Immutable { | ||
type CopyOutput = T; | ||
type MutableCopyOutput = T; | ||
} | ||
impl<T: ?Sized + Message, MutableSubclass: ?Sized + Message> Copyhelper<T> | ||
for ImmutableWithMutableSubclass<MutableSubclass> | ||
{ | ||
type CopyOutput = T; | ||
type MutableCopyOutput = MutableSubclass; | ||
} | ||
impl<T: ?Sized + Message, ImmutableSuperclass: ?Sized + Message> Copyhelper<T> | ||
for Mutable<ImmutableSuperclass> | ||
{ | ||
type CopyOutput = ImmutableSuperclass; | ||
type MutableCopyOutput = T; | ||
} | ||
impl<T: ?Sized + Message> Copyhelper<T> for InteriorMutable { | ||
type CopyOutput = T; | ||
type MutableCopyOutput = T; | ||
} | ||
impl<T: ?Sized + Message> Copyhelper<T> for MainThreadOnly { | ||
type CopyOutput = T; | ||
type MutableCopyOutput = T; | ||
} | ||
} | ||
|
||
/// TODO | ||
/// | ||
/// Note that the `mutableCopy` selector must return an owned object! | ||
pub unsafe trait NSMutableCopying: Message { | ||
/// The output type. | ||
/// | ||
/// This is usually `Self`, but e.g. `NSString` returns `NSMutableString`. | ||
type Output: Message; | ||
extern_protocol!( | ||
pub unsafe trait NSCopying { | ||
#[method_id(copy)] | ||
fn copy(&self) -> Id<<Self::Kind as private::Copyhelper<Self>>::CopyOutput> | ||
where | ||
Self: ClassType, | ||
Self::Kind: private::Copyhelper<Self>; | ||
} | ||
|
||
fn mutable_copy(&self) -> Id<Self::Output, Owned> { | ||
unsafe { msg_send_id![self, mutableCopy] } | ||
unsafe impl ProtocolType for dyn NSCopying {} | ||
); | ||
|
||
extern_protocol!( | ||
/// TODO | ||
/// | ||
/// Note that the `mutableCopy` selector must return an owned object! | ||
pub unsafe trait NSMutableCopying { | ||
#[method_id(mutableCopy)] | ||
fn mutableCopy( | ||
&self, | ||
) -> Id<<Self::Kind as private::Copyhelper<Self>>::MutableCopyOutput, Owned> | ||
where | ||
Self: ClassType, | ||
Self::Kind: private::Copyhelper<Self>; | ||
} | ||
} | ||
|
||
unsafe impl ProtocolType for dyn NSMutableCopying {} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters