use crate::declare::__IdReturnValue;
use crate::rc::{Allocated, Id};
use crate::{ClassType, Message, MessageReceiver};
use super::{CopyOrMutCopy, Init, MaybeUnwrap, New, Other};
use crate::mutability;
pub trait MessageRecieveId<Receiver, Ret> {
fn into_return(obj: Ret) -> __IdReturnValue;
}
impl<Receiver, Ret> MessageRecieveId<Receiver, Ret> for New
where
Receiver: MessageReceiver,
Ret: MaybeOptionId,
{
#[inline]
fn into_return(obj: Ret) -> __IdReturnValue {
obj.consumed_return()
}
}
impl<Ret, T> MessageRecieveId<Allocated<T>, Ret> for Init
where
T: Message,
Ret: MaybeOptionId<Input = Id<T>>,
{
#[inline]
fn into_return(obj: Ret) -> __IdReturnValue {
obj.consumed_return()
}
}
impl<Receiver, Ret> MessageRecieveId<Receiver, Ret> for CopyOrMutCopy
where
Receiver: MessageReceiver,
Ret: MaybeOptionId,
{
#[inline]
fn into_return(obj: Ret) -> __IdReturnValue {
obj.consumed_return()
}
}
impl<Receiver, Ret> MessageRecieveId<Receiver, Ret> for Other
where
Receiver: MessageReceiver,
Ret: MaybeOptionId,
{
#[inline]
fn into_return(obj: Ret) -> __IdReturnValue {
obj.autorelease_return()
}
}
pub trait MaybeOptionId: MaybeUnwrap {
fn consumed_return(self) -> __IdReturnValue;
fn autorelease_return(self) -> __IdReturnValue;
}
impl<T: Message> MaybeOptionId for Id<T> {
#[inline]
fn consumed_return(self) -> __IdReturnValue {
let ptr: *mut T = Id::consume_as_ptr(self);
__IdReturnValue(ptr.cast())
}
#[inline]
fn autorelease_return(self) -> __IdReturnValue {
let ptr: *mut T = Id::autorelease_return(self);
__IdReturnValue(ptr.cast())
}
}
impl<T: Message> MaybeOptionId for Option<Id<T>> {
#[inline]
fn consumed_return(self) -> __IdReturnValue {
let ptr: *mut T = Id::consume_as_ptr_option(self);
__IdReturnValue(ptr.cast())
}
#[inline]
fn autorelease_return(self) -> __IdReturnValue {
let ptr: *mut T = Id::autorelease_return_option(self);
__IdReturnValue(ptr.cast())
}
}
pub trait ValidSubclassMutability<T: mutability::Mutability> {}
impl ValidSubclassMutability<mutability::Immutable> for mutability::Root {}
impl ValidSubclassMutability<mutability::Mutable> for mutability::Root {}
impl<MS, IS> ValidSubclassMutability<mutability::ImmutableWithMutableSubclass<MS>>
for mutability::Root
where
MS: ?Sized + ClassType<Mutability = mutability::MutableWithImmutableSuperclass<IS>>,
IS: ?Sized + ClassType<Mutability = mutability::ImmutableWithMutableSubclass<MS>>,
{
}
impl ValidSubclassMutability<mutability::InteriorMutable> for mutability::Root {}
impl ValidSubclassMutability<mutability::MainThreadOnly> for mutability::Root {}
impl ValidSubclassMutability<mutability::Immutable> for mutability::Immutable {}
impl ValidSubclassMutability<mutability::Mutable> for mutability::Mutable {}
impl<MS, IS> ValidSubclassMutability<mutability::MutableWithImmutableSuperclass<IS>>
for mutability::ImmutableWithMutableSubclass<MS>
where
MS: ?Sized + ClassType<Mutability = mutability::MutableWithImmutableSuperclass<IS>>,
IS: ?Sized + ClassType<Mutability = mutability::ImmutableWithMutableSubclass<MS>>,
{
}
impl<MS: ?Sized + ClassType> ValidSubclassMutability<mutability::Immutable>
for mutability::ImmutableWithMutableSubclass<MS>
{
}
impl<IS: ?Sized + ClassType> ValidSubclassMutability<mutability::Mutable>
for mutability::MutableWithImmutableSuperclass<IS>
{
}
impl ValidSubclassMutability<mutability::InteriorMutable> for mutability::InteriorMutable {}
impl ValidSubclassMutability<mutability::MainThreadOnly> for mutability::InteriorMutable {}
impl ValidSubclassMutability<mutability::MainThreadOnly> for mutability::MainThreadOnly {}
#[inline]
pub fn assert_mutability_matches_superclass_mutability<T>()
where
T: ?Sized + ClassType,
T::Super: ClassType,
T::Mutability: mutability::Mutability,
<T::Super as ClassType>::Mutability: ValidSubclassMutability<T::Mutability>,
{
}