@@ -752,15 +752,15 @@ macro_rules! __inner_declare_class {
752
752
///
753
753
/// # Examples
754
754
///
755
- /// Declare a class `MyCustomObject` with a few instance variables and
756
- /// methods.
755
+ /// Declare a class `MyCustomObject` that inherits `NSObject`, has a few
756
+ /// instance variables and methods, and implements the `NSCopying` protocol .
757
757
///
758
758
/// ```
759
759
/// use std::os::raw::c_int;
760
760
/// use objc2::{msg_send, msg_send_bool, msg_send_id};
761
761
/// use objc2::rc::{Id, Owned};
762
762
/// use objc2::runtime::Bool;
763
- /// use objc2_foundation::{declare_class, NSObject};
763
+ /// use objc2_foundation::{declare_class, NSCopying, NSObject, NSZone };
764
764
/// #
765
765
/// # #[cfg(feature = "gnustep-1-7")]
766
766
/// # unsafe { objc2::__gnustep_hack::get_class_to_force_linkage() };
@@ -797,6 +797,15 @@ macro_rules! __inner_declare_class {
797
797
/// Bool::YES
798
798
/// }
799
799
/// }
800
+ ///
801
+ /// unsafe impl protocol NSCopying {
802
+ /// @sel(copyWithZone:)
803
+ /// fn copy_with_zone(&self, _zone: *const NSZone) -> *mut Self {
804
+ /// let mut obj = Self::new(*self.foo);
805
+ /// *obj.bar = *self.bar;
806
+ /// obj.autorelease_return()
807
+ /// }
808
+ /// }
800
809
/// }
801
810
///
802
811
/// impl MyCustomObject {
@@ -814,11 +823,19 @@ macro_rules! __inner_declare_class {
814
823
/// }
815
824
/// }
816
825
///
826
+ /// unsafe impl NSCopying for MyCustomObject {
827
+ /// type Ownership = Owned;
828
+ /// type Output = Self;
829
+ /// }
830
+ ///
817
831
/// fn main() {
818
832
/// let obj = MyCustomObject::new(3);
819
833
/// assert_eq!(*obj.foo, 3);
820
834
/// assert_eq!(*obj.bar, 42);
835
+ ///
836
+ /// let obj = obj.copy();
821
837
/// assert_eq!(obj.get_foo(), 3);
838
+ ///
822
839
/// assert!(MyCustomObject::my_class_method());
823
840
/// }
824
841
/// ```
@@ -828,7 +845,7 @@ macro_rules! __inner_declare_class {
828
845
/// ```text
829
846
/// #import <Foundation/Foundation.h>
830
847
///
831
- /// @interface MyCustomObject: NSObject {
848
+ /// @interface MyCustomObject: NSObject <NSCopying> {
832
849
/// int bar;
833
850
/// }
834
851
///
@@ -861,20 +878,33 @@ macro_rules! __inner_declare_class {
861
878
/// return YES;
862
879
/// }
863
880
///
881
+ /// - (id)copyWithZone:(NSZone *)_zone {
882
+ /// MyCustomObject* obj = [[MyCustomObject alloc] initWithFoo: self->foo];
883
+ /// obj->bar = self->bar;
884
+ /// return obj;
885
+ /// }
886
+ ///
864
887
/// @end
865
888
/// ```
866
889
#[ macro_export]
867
890
macro_rules! declare_class {
868
891
{
869
892
$( #[ $m: meta] ) *
870
- unsafe $v: vis struct $name: ident: $inherits: ident $( , $inheritance_rest: ident ) * $ ( <$ ( $protocols : ident ) ,+ $ ( , ) ?> ) ? {
893
+ unsafe $v: vis struct $name: ident: $inherits: ty $( , $inheritance_rest: ty ) * {
871
894
$( $ivar_v: vis $ivar: ident: $ivar_ty: ty, ) *
872
895
}
873
896
874
897
$( #[ $impl_m: meta] ) *
875
898
unsafe impl {
876
899
$( $methods: tt) *
877
900
}
901
+
902
+ $(
903
+ $( #[ $impl_protocol_m: meta] ) *
904
+ unsafe impl protocol $protocols: ident {
905
+ $( $protocol_methods: tt) *
906
+ }
907
+ ) ,*
878
908
} => {
879
909
$(
880
910
#[ allow( non_camel_case_types) ]
@@ -916,13 +946,6 @@ macro_rules! declare_class {
916
946
let superclass = <$inherits>:: class( ) ;
917
947
let mut builder = ClassBuilder :: new( stringify!( $name) , superclass) . unwrap( ) ;
918
948
919
- // Implement protocols
920
- $(
921
- $(
922
- builder. add_protocol( Protocol :: get( stringify!( $protocols) ) . unwrap( ) ) ;
923
- ) +
924
- ) ?
925
-
926
949
$(
927
950
builder. add_ivar:: <<$ivar as $crate:: objc2:: declare:: IvarType >:: Type >(
928
951
<$ivar as $crate:: objc2:: declare:: IvarType >:: NAME
@@ -940,6 +963,22 @@ macro_rules! declare_class {
940
963
}
941
964
}
942
965
966
+ // Implement protocols
967
+ $(
968
+ builder. add_protocol( Protocol :: get( stringify!( $protocols) ) . unwrap( ) ) ;
969
+
970
+ // SAFETY: Upheld by caller
971
+ unsafe {
972
+ $crate:: __inner_declare_class! {
973
+ @rewrite_methods
974
+ @register_out
975
+ @builder
976
+
977
+ $( $protocol_methods) *
978
+ }
979
+ }
980
+ ) *
981
+
943
982
let _cls = builder. register( ) ;
944
983
} ) ;
945
984
@@ -958,6 +997,20 @@ macro_rules! declare_class {
958
997
$( $methods) *
959
998
}
960
999
}
1000
+
1001
+ // Protocol methods
1002
+ $(
1003
+ $( #[ $impl_protocol_m] ) *
1004
+ impl $name {
1005
+ $crate:: __inner_declare_class! {
1006
+ @rewrite_methods
1007
+ @method_out
1008
+ @__builder
1009
+
1010
+ $( $protocol_methods) *
1011
+ }
1012
+ }
1013
+ ) *
961
1014
} ;
962
1015
}
963
1016
0 commit comments