diff --git a/objc_foundation/examples/example.rs b/examples/foundation.rs similarity index 97% rename from objc_foundation/examples/example.rs rename to examples/foundation.rs index 55c981e4a..310896608 100644 --- a/objc_foundation/examples/example.rs +++ b/examples/foundation.rs @@ -1,5 +1,3 @@ -extern crate objc_foundation; - use objc_foundation::{ INSArray, INSCopying, INSDictionary, INSObject, INSString, NSArray, NSDictionary, NSObject, NSString, diff --git a/objc_foundation/examples/custom_class.rs b/examples/foundation_custom_class.rs similarity index 97% rename from objc_foundation/examples/custom_class.rs rename to examples/foundation_custom_class.rs index 919b88cd1..22bef447b 100644 --- a/objc_foundation/examples/custom_class.rs +++ b/examples/foundation_custom_class.rs @@ -1,10 +1,7 @@ -#[macro_use] -extern crate objc; -extern crate objc_foundation; - use std::sync::{Once, ONCE_INIT}; use objc::declare::ClassDecl; +use objc::msg_send; use objc::runtime::{Class, Object, Sel}; use objc::Message; use objc_foundation::{INSObject, NSObject}; diff --git a/objc/examples/example.rs b/examples/objc.rs similarity index 95% rename from objc/examples/example.rs rename to examples/objc.rs index a6f06b3d2..5026a77b6 100644 --- a/objc/examples/example.rs +++ b/examples/objc.rs @@ -1,9 +1,6 @@ -#[macro_use] -extern crate objc; - use objc::rc::StrongPtr; use objc::runtime::{Class, Object}; -use objc::Encode; +use objc::{class, msg_send, Encode}; fn main() { // Get a class diff --git a/objc/src/declare.rs b/objc/src/declare.rs index 3f39b251a..6e395d8bc 100644 --- a/objc/src/declare.rs +++ b/objc/src/declare.rs @@ -10,7 +10,7 @@ The following example demonstrates declaring a class named `MyNumber` that has one ivar, a `u32` named `_number` and a `number` method that returns it: ``` no_run -# #[macro_use] extern crate objc; +# use objc::class; # use objc::declare::ClassDecl; # use objc::runtime::{Class, Object, Sel}; # fn main() { @@ -91,7 +91,7 @@ fn count_args(sel: Sel) -> usize { sel.name().chars().filter(|&c| c == ':').count() } -fn method_type_encoding(ret: &Encoding, args: &[Encoding]) -> CString { +fn method_type_encoding(ret: &Encoding<'_>, args: &[Encoding<'_>]) -> CString { // First two arguments are always self and the selector let mut types = format!("{}{}{}", ret, <*mut Object>::ENCODING, Sel::ENCODING); for enc in args { @@ -123,7 +123,7 @@ impl ClassDecl { if cls.is_null() { None } else { - Some(ClassDecl { cls: cls }) + Some(ClassDecl { cls }) } } @@ -159,8 +159,11 @@ impl ClassDecl { /// Adds a method with the given name and implementation to self. /// Panics if the method wasn't sucessfully added /// or if the selector and function take different numbers of arguments. - /// Unsafe because the caller must ensure that the types match those that - /// are expected when the method is invoked from Objective-C. + /// + /// # Safety + /// + /// The caller must ensure that the types match those that are expected + /// when the method is invoked from Objective-C. pub unsafe fn add_method(&mut self, sel: Sel, func: F) where F: MethodImplementation, @@ -182,8 +185,11 @@ impl ClassDecl { /// Adds a class method with the given name and implementation to self. /// Panics if the method wasn't sucessfully added /// or if the selector and function take different numbers of arguments. - /// Unsafe because the caller must ensure that the types match those that - /// are expected when the method is invoked from Objective-C. + /// + /// # Safety + /// + /// The caller must ensure that the types match those that are expected + /// when the method is invoked from Objective-C. pub unsafe fn add_class_method(&mut self, sel: Sel, func: F) where F: MethodImplementation, @@ -262,7 +268,7 @@ impl ProtocolDecl { if proto.is_null() { None } else { - Some(ProtocolDecl { proto: proto }) + Some(ProtocolDecl { proto }) } } diff --git a/objc/src/exception.rs b/objc/src/exception.rs index 3e16c92cf..f5dab0992 100644 --- a/objc/src/exception.rs +++ b/objc/src/exception.rs @@ -3,6 +3,19 @@ use objc_exception; use crate::rc::StrongPtr; use crate::runtime::Object; +// Comment copied from `objc_exception` + +/// Tries to execute the given closure and catches an Objective-C exception +/// if one is thrown. +/// +/// Returns a `Result` that is either `Ok` if the closure succeeded without an +/// exception being thrown, or an `Err` with a pointer to an exception if one +/// was thrown. The exception is retained and so must be released. +/// +/// # Safety +/// +/// This encourages unwinding through the closure from Objective-C, which is +/// not safe. pub unsafe fn catch_exception(closure: F) -> Result where F: FnOnce() -> R, diff --git a/objc/src/lib.rs b/objc/src/lib.rs index 2f88a9796..40d9e56a7 100644 --- a/objc/src/lib.rs +++ b/objc/src/lib.rs @@ -6,7 +6,7 @@ Objective-C Runtime bindings and wrapper for Rust. Objective-C objects can be messaged using the [`msg_send!`](macro.msg_send!.html) macro: ``` no_run -# #[macro_use] extern crate objc; +# use objc::{class, msg_send}; # use objc::runtime::{BOOL, Class, Object}; # fn main() { # unsafe { @@ -63,11 +63,7 @@ The bindings can be used on Linux or *BSD utilizing the #![crate_name = "objc"] #![crate_type = "lib"] #![warn(missing_docs)] - -extern crate malloc_buf; -extern crate objc_encode; -#[cfg(feature = "exception")] -extern crate objc_exception; +#![allow(clippy::missing_safety_doc)] pub use objc_encode::{Encode, Encoding}; diff --git a/objc/src/macros.rs b/objc/src/macros.rs index 328f7a0c4..1bbb71486 100644 --- a/objc/src/macros.rs +++ b/objc/src/macros.rs @@ -6,7 +6,6 @@ To check for a class that may not exist, use `Class::get`. # Example ``` no_run -# #[macro_use] extern crate objc; # fn main() { let cls = class!(NSObject); # } @@ -31,7 +30,6 @@ Registers a selector, returning a `Sel`. # Example ``` -# #[macro_use] extern crate objc; # fn main() { let sel = sel!(description); let sel = sel!(setObject:forKey:); @@ -64,7 +62,6 @@ Variadic arguments are not currently supported. # Example ``` no_run -# #[macro_use] extern crate objc; # use objc::runtime::Object; # fn main() { # unsafe { diff --git a/objc/src/message/apple/mod.rs b/objc/src/message/apple/mod.rs index 3c9a9f71f..6ed5140be 100644 --- a/objc/src/message/apple/mod.rs +++ b/objc/src/message/apple/mod.rs @@ -42,7 +42,7 @@ where { let sup = Super { receiver: obj as *mut T as *mut Object, - superclass: superclass, + superclass, }; let receiver = &sup as *const Super as *mut Object; let msg_send_fn = msg_send_super_fn::(); diff --git a/objc/src/message/mod.rs b/objc/src/message/mod.rs index 301c16a71..07a7e4d92 100644 --- a/objc/src/message/mod.rs +++ b/objc/src/message/mod.rs @@ -70,6 +70,7 @@ pub unsafe trait Message { send_message(self, sel, args) } + #[allow(missing_docs)] #[cfg(feature = "verify_message")] unsafe fn send_message(&self, sel: Sel, args: A) -> Result where @@ -90,7 +91,7 @@ pub unsafe trait Message { # Example ``` no_run - # #[macro_use] extern crate objc; + # use objc::{class, msg_send}; # use objc::runtime::{BOOL, Class, Object}; # use objc::Message; # fn main() { @@ -195,7 +196,7 @@ Currently, an error may be returned in two cases: pub struct MessageError(String); impl fmt::Display for MessageError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.0, f) } } @@ -207,7 +208,7 @@ impl Error for MessageError { } impl<'a> From> for MessageError { - fn from(err: VerificationError) -> MessageError { + fn from(err: VerificationError<'_>) -> MessageError { MessageError(err.to_string()) } } @@ -284,8 +285,7 @@ where #[cfg(test)] mod tests { - use super::Message; - use crate::runtime::Object; + use super::*; use crate::test_utils; #[test] diff --git a/objc/src/message/verify.rs b/objc/src/message/verify.rs index 06a5a6b37..7b401cabc 100644 --- a/objc/src/message/verify.rs +++ b/objc/src/message/verify.rs @@ -12,7 +12,7 @@ pub enum VerificationError<'a> { } impl<'a> fmt::Display for VerificationError<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { VerificationError::NilReceiver(sel) => { write!(f, "Messsaging {:?} to nil", sel) @@ -55,7 +55,7 @@ impl<'a> fmt::Display for VerificationError<'a> { } } -pub fn verify_message_signature(cls: &Class, sel: Sel) -> Result<(), VerificationError> +pub fn verify_message_signature(cls: &Class, sel: Sel) -> Result<(), VerificationError<'_>> where A: EncodeArguments, R: Encode, diff --git a/objc/src/rc/mod.rs b/objc/src/rc/mod.rs index b609eb55a..4bb40b565 100644 --- a/objc/src/rc/mod.rs +++ b/objc/src/rc/mod.rs @@ -16,7 +16,7 @@ For more information on Objective-C's reference counting, see Apple's documentat # Example ``` no_run -# #[macro_use] extern crate objc; +# use objc::{class, msg_send}; # use objc::rc::{autoreleasepool, StrongPtr}; # fn main() { // StrongPtr will release the object when dropped @@ -91,8 +91,11 @@ mod tests { let weak = obj.weak(); let weak2 = weak.clone(); - let strong = weak2.load(); + + let strong = weak.load(); + let strong2 = weak2.load(); assert!(*strong == *obj); + assert!(*strong2 == *obj); } #[test] diff --git a/objc/src/rc/strong.rs b/objc/src/rc/strong.rs index 4536586ca..971692d63 100644 --- a/objc/src/rc/strong.rs +++ b/objc/src/rc/strong.rs @@ -12,14 +12,20 @@ impl StrongPtr { /// Constructs a `StrongPtr` to a newly created object that already has a /// +1 retain count. This will not retain the object. /// When dropped, the object will be released. - /// Unsafe because the caller must ensure the given object pointer is valid. + /// + /// # Safety + /// + /// The caller must ensure the given object pointer is valid. pub unsafe fn new(ptr: *mut Object) -> Self { StrongPtr(ptr) } /// Retains the given object and constructs a `StrongPtr` to it. /// When dropped, the object will be released. - /// Unsafe because the caller must ensure the given object pointer is valid. + /// + /// # Safety + /// + /// The caller must ensure the given object pointer is valid. pub unsafe fn retain(ptr: *mut Object) -> Self { StrongPtr(runtime::objc_retain(ptr)) } @@ -65,7 +71,7 @@ impl Deref for StrongPtr { } impl fmt::Pointer for StrongPtr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.0, f) } } diff --git a/objc/src/rc/weak.rs b/objc/src/rc/weak.rs index 4a748f9f4..975fb94bc 100644 --- a/objc/src/rc/weak.rs +++ b/objc/src/rc/weak.rs @@ -14,7 +14,10 @@ pub struct WeakPtr(Box>); impl WeakPtr { /// Constructs a `WeakPtr` to the given object. - /// Unsafe because the caller must ensure the given object pointer is valid. + /// + /// # Safety + /// + /// The caller must ensure the given object pointer is valid. pub unsafe fn new(obj: *mut Object) -> Self { let ptr = Box::new(UnsafeCell::new(ptr::null_mut())); runtime::objc_initWeak(ptr.get(), obj); diff --git a/objc/src/runtime.rs b/objc/src/runtime.rs index 0c4eaa0d5..f1a0732ff 100644 --- a/objc/src/runtime.rs +++ b/objc/src/runtime.rs @@ -74,6 +74,7 @@ pub struct Object { /// A pointer to the start of a method implementation. pub type Imp = unsafe extern "C" fn(); +#[allow(missing_docs)] #[link(name = "objc", kind = "dylib")] extern "C" { pub fn sel_registerName(name: *const c_char) -> Sel; @@ -176,10 +177,14 @@ impl Sel { /// Wraps a raw pointer to a selector into a `Sel` object. /// + /// # Safety + /// + /// The pointer must a valid, registered selector. + /// /// This is almost never what you want; use `Sel::register()` instead. #[inline] pub unsafe fn from_ptr(ptr: *const c_void) -> Sel { - Sel { ptr: ptr } + Sel { ptr } } /// Returns a pointer to the raw selector. @@ -210,7 +215,7 @@ impl Clone for Sel { } impl fmt::Debug for Sel { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.name()) } } @@ -405,7 +410,7 @@ impl PartialEq for Class { impl Eq for Class {} impl fmt::Debug for Class { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.name()) } } @@ -464,7 +469,7 @@ impl PartialEq for Protocol { impl Eq for Protocol {} impl fmt::Debug for Protocol { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.name()) } } @@ -477,8 +482,10 @@ impl Object { /// Returns a reference to the ivar of self with the given name. /// Panics if self has no ivar with the given name. - /// Unsafe because the caller must ensure that the ivar is actually - /// of type `T`. + /// + /// # Safety + /// + /// The caller must ensure that the ivar is actually of type `T`. pub unsafe fn get_ivar(&self, name: &str) -> &T where T: Encode, @@ -502,8 +509,10 @@ impl Object { /// Returns a mutable reference to the ivar of self with the given name. /// Panics if self has no ivar with the given name. - /// Unsafe because the caller must ensure that the ivar is actually - /// of type `T`. + /// + /// # Safety + /// + /// The caller must ensure that the ivar is actually of type `T`. pub unsafe fn get_mut_ivar(&mut self, name: &str) -> &mut T where T: Encode, @@ -527,8 +536,10 @@ impl Object { /// Sets the value of the ivar of self with the given name. /// Panics if self has no ivar with the given name. - /// Unsafe because the caller must ensure that the ivar is actually - /// of type `T`. + /// + /// # Safety + /// + /// The caller must ensure that the ivar is actually of type `T`. pub unsafe fn set_ivar(&mut self, name: &str, value: T) where T: Encode, @@ -538,7 +549,7 @@ impl Object { } impl fmt::Debug for Object { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "<{:?}: {:p}>", self.class(), self) } } diff --git a/objc/src/test_utils.rs b/objc/src/test_utils.rs index 737965075..2e2277b15 100644 --- a/objc/src/test_utils.rs +++ b/objc/src/test_utils.rs @@ -13,7 +13,7 @@ pub struct CustomObject { impl CustomObject { fn new(class: &Class) -> Self { let obj = unsafe { runtime::class_createInstance(class, 0) }; - CustomObject { obj: obj } + CustomObject { obj } } } @@ -40,6 +40,7 @@ impl Drop for CustomObject { } #[derive(Eq, PartialEq)] +#[repr(C)] pub struct CustomStruct { pub a: u64, pub b: u64, diff --git a/objc/tests-ios/prelude.rs b/objc/tests-ios/prelude.rs index 2eabd4c83..8ec4c55ad 100644 --- a/objc/tests-ios/prelude.rs +++ b/objc/tests-ios/prelude.rs @@ -1,6 +1,3 @@ -#[macro_use] -extern crate objc; - use objc::rc::*; use objc::runtime::*; pub use objc::*; diff --git a/objc/tests/use_macros.rs b/objc/tests/use_macros.rs index b078503f0..8039c0ca6 100644 --- a/objc/tests/use_macros.rs +++ b/objc/tests/use_macros.rs @@ -1,7 +1,5 @@ #![cfg(any(target_os = "macos", target_os = "ios"))] -extern crate objc; - use objc::runtime::Object; use objc::{class, msg_send, sel}; diff --git a/objc_encode/examples/core_graphics.rs b/objc_encode/examples/core_graphics.rs index 4c0b7f75b..ed2f7c85a 100644 --- a/objc_encode/examples/core_graphics.rs +++ b/objc_encode/examples/core_graphics.rs @@ -1,5 +1,3 @@ -extern crate objc_encode; - use objc_encode::{Encode, Encoding}; #[cfg(target_pointer_width = "32")] diff --git a/objc_encode/src/encoding.rs b/objc_encode/src/encoding.rs index 4932a54fe..868c5d4cc 100644 --- a/objc_encode/src/encoding.rs +++ b/objc_encode/src/encoding.rs @@ -36,7 +36,7 @@ pub enum Encoding<'a> { } impl fmt::Display for Encoding<'_> { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { use Encoding::*; let code = match *self { Char => "c", @@ -94,7 +94,7 @@ impl PartialEq for Encoding<'_> { } impl PartialEq> for str { - fn eq(&self, other: &Encoding) -> bool { + fn eq(&self, other: &Encoding<'_>) -> bool { parse::eq_enc(self, other) } } diff --git a/objc_encode/src/parse.rs b/objc_encode/src/parse.rs index e935043c4..a0dfaca7c 100644 --- a/objc_encode/src/parse.rs +++ b/objc_encode/src/parse.rs @@ -2,7 +2,7 @@ use crate::Encoding; -const QUALIFIERS: &'static [char] = &[ +const QUALIFIERS: &[char] = &[ 'r', // const 'n', // in 'N', // inout @@ -12,7 +12,7 @@ const QUALIFIERS: &'static [char] = &[ 'V', // oneway ]; -fn rm_enc_prefix<'a>(s: &'a str, enc: &Encoding) -> Option<&'a str> { +fn rm_enc_prefix<'a>(s: &'a str, enc: &Encoding<'_>) -> Option<&'a str> { use Encoding::*; let code = match *enc { Char => "c", @@ -36,43 +36,43 @@ fn rm_enc_prefix<'a>(s: &'a str, enc: &Encoding) -> Option<&'a str> { Sel => ":", Unknown => "?", BitField(b) => { - let s = rm_prefix(s, "b")?; + let s = s.strip_prefix('b')?; return rm_int_prefix(s, b); } Pointer(t) => { - let s = rm_prefix(s, "^")?; + let s = s.strip_prefix('^')?; return rm_enc_prefix(s, t); } Array(len, item) => { let mut s = s; - s = rm_prefix(s, "[")?; + s = s.strip_prefix('[')?; s = rm_int_prefix(s, len)?; s = rm_enc_prefix(s, item)?; - return rm_prefix(s, "]"); + return s.strip_prefix(']'); } Struct(name, fields) => { let mut s = s; - s = rm_prefix(s, "{")?; - s = rm_prefix(s, name)?; - s = rm_prefix(s, "=")?; + s = s.strip_prefix('{')?; + s = s.strip_prefix(name)?; + s = s.strip_prefix('=')?; for field in fields { s = rm_enc_prefix(s, field)?; } - return rm_prefix(s, "}"); + return s.strip_prefix('}'); } Union(name, members) => { let mut s = s; - s = rm_prefix(s, "(")?; - s = rm_prefix(s, name)?; - s = rm_prefix(s, "=")?; + s = s.strip_prefix('(')?; + s = s.strip_prefix(name)?; + s = s.strip_prefix('=')?; for member in members { s = rm_enc_prefix(s, member)?; } - return rm_prefix(s, ")"); + return s.strip_prefix(')'); } }; - rm_prefix(s, code) + s.strip_prefix(code) } fn chomp_int(s: &str) -> Option<(u32, &str)> { @@ -88,15 +88,7 @@ fn rm_int_prefix(s: &str, other: u32) -> Option<&str> { chomp_int(s).and_then(|(n, t)| if other == n { Some(t) } else { None }) } -fn rm_prefix<'a>(s: &'a str, other: &str) -> Option<&'a str> { - if s.starts_with(other) { - Some(&s[other.len()..]) - } else { - None - } -} - -pub fn eq_enc(s: &str, enc: &Encoding) -> bool { +pub fn eq_enc(s: &str, enc: &Encoding<'_>) -> bool { // strip qualifiers let s = s.trim_start_matches(QUALIFIERS); diff --git a/objc_exception/Cargo.toml b/objc_exception/Cargo.toml index 7bb99c7cf..ea842f180 100644 --- a/objc_exception/Cargo.toml +++ b/objc_exception/Cargo.toml @@ -2,6 +2,7 @@ name = "objc_exception" version = "0.1.2" authors = ["Steven Sheldon"] +edition = "2018" description = "Rust interface for Objective-C's throw and try/catch statements." keywords = ["objective-c", "osx", "ios"] diff --git a/objc_exception/build.rs b/objc_exception/build.rs index ba728b6e1..a17b0cc09 100644 --- a/objc_exception/build.rs +++ b/objc_exception/build.rs @@ -1,5 +1,3 @@ -extern crate cc; - fn main() { cc::Build::new() .file("extern/exception.m") diff --git a/objc_exception/src/lib.rs b/objc_exception/src/lib.rs index b79f1367b..5b591257e 100644 --- a/objc_exception/src/lib.rs +++ b/objc_exception/src/lib.rs @@ -10,7 +10,7 @@ extern "C" {} extern "C" { fn RustObjCExceptionThrow(exception: *mut c_void); fn RustObjCExceptionTryCatch( - try: extern "C" fn(*mut c_void), + r#try: extern "C" fn(*mut c_void), context: *mut c_void, error: *mut *mut c_void, ) -> c_int; @@ -22,7 +22,10 @@ pub enum Exception {} /// Throws an Objective-C exception. /// The argument must be a pointer to an Objective-C object. /// -/// Unsafe because this unwinds from Objective-C. +/// # Safety +/// +/// This unwinds from Objective-C, and the exception must be caught using an +/// Objective-C exception handler. pub unsafe fn throw(exception: *mut Exception) -> ! { RustObjCExceptionThrow(exception as *mut _); unreachable!(); @@ -64,9 +67,11 @@ where /// exception being thrown, or an `Err` with a pointer to an exception if one /// was thrown. The exception is retained and so must be released. /// -/// Unsafe because this encourages unwinding through the closure from +/// # Safety +/// +/// This encourages unwinding through the closure from /// Objective-C, which is not safe. -pub unsafe fn try(closure: F) -> Result +pub unsafe fn r#try(closure: F) -> Result where F: FnOnce() -> R, { @@ -83,15 +88,15 @@ where #[cfg(test)] mod tests { - use super::{throw, try}; + use super::{r#try, throw}; use std::ptr; #[test] fn test_try() { unsafe { let s = "Hello".to_string(); - let result = try(move || { - if s.len() > 0 { + let result = r#try(move || { + if !s.is_empty() { throw(ptr::null_mut()); } s.len() @@ -99,7 +104,7 @@ mod tests { assert!(result.unwrap_err() == ptr::null_mut()); let mut s = "Hello".to_string(); - let result = try(move || { + let result = r#try(move || { s.push_str(", World!"); s }); diff --git a/objc_foundation/Cargo.toml b/objc_foundation/Cargo.toml index 17c4a0ed4..02c4091c6 100644 --- a/objc_foundation/Cargo.toml +++ b/objc_foundation/Cargo.toml @@ -2,6 +2,7 @@ name = "objc-foundation" version = "0.1.1" authors = ["Steven Sheldon"] +edition = "2018" description = "Rust wrapper for Objective-C's Foundation framework." keywords = ["objective-c", "osx", "ios", "cocoa", "uikit"] diff --git a/objc_foundation/src/array.rs b/objc_foundation/src/array.rs index 527e8123a..b05ec7a66 100644 --- a/objc_foundation/src/array.rs +++ b/objc_foundation/src/array.rs @@ -6,7 +6,7 @@ use std::os::raw::c_void; use objc::runtime::{Class, Object}; use objc_id::{Id, Owned, Ownership, ShareId, Shared}; -use {INSCopying, INSFastEnumeration, INSMutableCopying, INSObject, NSEnumerator}; +use super::{INSCopying, INSFastEnumeration, INSMutableCopying, INSObject, NSEnumerator}; #[repr(isize)] #[derive(Clone, Copy)] @@ -400,8 +400,8 @@ pub type NSMutableSharedArray = NSMutableArray; #[cfg(test)] mod tests { use super::{INSArray, INSMutableArray, NSArray, NSMutableArray}; + use crate::{INSObject, INSString, NSObject, NSString}; use objc_id::Id; - use {INSObject, INSString, NSObject, NSString}; fn sample_array(len: usize) -> Id> { let mut vec = Vec::with_capacity(len); @@ -453,7 +453,7 @@ mod tests { assert!(middle_objs[1] == array.object_at(2)); let empty_objs = array.objects_in_range(1..1); - assert!(empty_objs.len() == 0); + assert!(empty_objs.is_empty()); let all_objs = array.objects_in_range(0..4); assert!(all_objs.len() == 4); diff --git a/objc_foundation/src/data.rs b/objc_foundation/src/data.rs index 178291e5d..717ec728b 100644 --- a/objc_foundation/src/data.rs +++ b/objc_foundation/src/data.rs @@ -3,15 +3,19 @@ use std::ops::Range; use std::os::raw::c_void; use std::slice; +use super::{INSCopying, INSMutableCopying, INSObject, NSRange}; use block::{Block, ConcreteBlock}; use objc_id::Id; -use {INSCopying, INSMutableCopying, INSObject, NSRange}; pub trait INSData: INSObject { fn len(&self) -> usize { unsafe { msg_send![self, length] } } + fn is_empty(&self) -> bool { + self.len() == 0 + } + fn bytes(&self) -> &[u8] { let ptr: *const c_void = unsafe { msg_send![self, bytes] }; // The bytes pointer may be null for length zero @@ -128,7 +132,7 @@ impl INSMutableCopying for NSMutableData { #[cfg(test)] mod tests { use super::{INSData, INSMutableData, NSData, NSMutableData}; - use INSObject; + use crate::INSObject; #[test] fn test_bytes() { diff --git a/objc_foundation/src/dictionary.rs b/objc_foundation/src/dictionary.rs index 35260f9cf..3c29caff7 100644 --- a/objc_foundation/src/dictionary.rs +++ b/objc_foundation/src/dictionary.rs @@ -6,7 +6,7 @@ use std::ptr; use objc::runtime::Class; use objc_id::{Id, Owned, Ownership, ShareId}; -use {INSCopying, INSFastEnumeration, INSObject, NSArray, NSEnumerator, NSSharedArray}; +use super::{INSCopying, INSFastEnumeration, INSObject, NSArray, NSEnumerator, NSSharedArray}; unsafe fn from_refs(keys: &[&T], vals: &[&D::Value]) -> Id where @@ -164,8 +164,8 @@ where #[cfg(test)] mod tests { use super::{INSDictionary, NSDictionary}; + use crate::{INSArray, INSObject, INSString, NSObject, NSString}; use objc_id::Id; - use {INSArray, INSObject, INSString, NSObject, NSString}; fn sample_dict(key: &str) -> Id> { let string = NSString::from_str(key); diff --git a/objc_foundation/src/enumerator.rs b/objc_foundation/src/enumerator.rs index f3df042ba..c0860f642 100644 --- a/objc_foundation/src/enumerator.rs +++ b/objc_foundation/src/enumerator.rs @@ -7,7 +7,7 @@ use std::slice; use objc::runtime::Object; use objc_id::Id; -use INSObject; +use super::INSObject; pub struct NSEnumerator<'a, T> where @@ -21,6 +21,12 @@ impl<'a, T> NSEnumerator<'a, T> where T: INSObject, { + /// TODO + /// + /// # Safety + /// + /// The object pointer must be a valid `NSEnumerator` with `Owned` + /// ownership. pub unsafe fn from_ptr(ptr: *mut Object) -> NSEnumerator<'a, T> { NSEnumerator { id: Id::from_ptr(ptr), @@ -98,7 +104,7 @@ pub struct NSFastEnumerator<'a, C: 'a + INSFastEnumeration> { impl<'a, C: INSFastEnumeration> NSFastEnumerator<'a, C> { fn new(object: &C) -> NSFastEnumerator { NSFastEnumerator { - object: object, + object, ptr: ptr::null(), end: ptr::null(), @@ -129,7 +135,7 @@ impl<'a, C: INSFastEnumeration> NSFastEnumerator<'a, C> { } self.ptr = buf.as_ptr(); - self.end = unsafe { self.ptr.offset(buf.len() as isize) }; + self.end = unsafe { self.ptr.add(buf.len()) }; true } else { self.ptr = ptr::null(); @@ -158,7 +164,7 @@ impl<'a, C: INSFastEnumeration> Iterator for NSFastEnumerator<'a, C> { #[cfg(test)] mod tests { use super::INSFastEnumeration; - use {INSArray, INSValue, NSArray, NSValue}; + use crate::{INSArray, INSValue, NSArray, NSValue}; #[test] fn test_enumerator() { diff --git a/objc_foundation/src/lib.rs b/objc_foundation/src/lib.rs index 16f49cf87..6e1a6fa9c 100644 --- a/objc_foundation/src/lib.rs +++ b/objc_foundation/src/lib.rs @@ -3,8 +3,6 @@ #[macro_use] extern crate objc; -extern crate block; -extern crate objc_id; pub use self::array::{ INSArray, INSMutableArray, NSArray, NSComparisonResult, NSMutableArray, NSMutableSharedArray, diff --git a/objc_foundation/src/object.rs b/objc_foundation/src/object.rs index 77286ff50..b0b6b3e22 100644 --- a/objc_foundation/src/object.rs +++ b/objc_foundation/src/object.rs @@ -4,7 +4,7 @@ use objc::runtime::{Class, BOOL, NO}; use objc::Message; use objc_id::{Id, ShareId}; -use NSString; +use super::NSString; /* The Sized bound is unfortunate; ideally, objc objects would not be @@ -54,7 +54,7 @@ object_struct!(NSObject); #[cfg(test)] mod tests { use super::{INSObject, NSObject}; - use {INSString, NSString}; + use crate::{INSString, NSString}; #[test] fn test_is_equal() { diff --git a/objc_foundation/src/string.rs b/objc_foundation/src/string.rs index e7d9a9cff..34f38a810 100644 --- a/objc_foundation/src/string.rs +++ b/objc_foundation/src/string.rs @@ -5,7 +5,7 @@ use std::str; use objc_id::{Id, ShareId}; -use INSObject; +use super::INSObject; pub trait INSCopying: INSObject { type Output: INSObject; @@ -36,6 +36,10 @@ pub trait INSString: INSObject { unsafe { msg_send![self, lengthOfBytesUsingEncoding: UTF8_ENCODING] } } + fn is_empty(&self) -> bool { + self.len() == 0 + } + fn as_str(&self) -> &str { let bytes = unsafe { let bytes: *const c_char = msg_send![self, UTF8String]; diff --git a/objc_foundation/src/value.rs b/objc_foundation/src/value.rs index f534d5674..2f888d31f 100644 --- a/objc_foundation/src/value.rs +++ b/objc_foundation/src/value.rs @@ -1,7 +1,7 @@ use std::any::Any; use std::ffi::{CStr, CString}; use std::marker::PhantomData; -use std::mem; +use std::mem::MaybeUninit; use std::os::raw::{c_char, c_void}; use std::str; @@ -9,19 +9,18 @@ use objc::runtime::Class; use objc::{Encode, Encoding}; use objc_id::Id; -use {INSCopying, INSObject}; +use super::{INSCopying, INSObject}; pub trait INSValue: INSObject { type Value: 'static + Copy + Encode; fn value(&self) -> Self::Value { assert!(Self::Value::encode() == self.encoding()); + let mut value = MaybeUninit::::uninit(); + let ptr = value.as_mut_ptr() as *mut c_void; unsafe { - let mut value = mem::uninitialized::(); - let value_ptr: *mut Self::Value = &mut value; - let bytes = value_ptr as *mut c_void; - let _: () = msg_send![self, getValue: bytes]; - value + let _: () = msg_send![self, getValue: ptr]; + value.assume_init() } } @@ -79,8 +78,8 @@ where #[cfg(test)] mod tests { + use crate::{INSValue, NSValue}; use objc::Encode; - use {INSValue, NSValue}; #[test] fn test_value() { diff --git a/objc_id/Cargo.toml b/objc_id/Cargo.toml index 99598b913..71196c703 100644 --- a/objc_id/Cargo.toml +++ b/objc_id/Cargo.toml @@ -2,6 +2,7 @@ name = "objc_id" version = "0.1.1" authors = ["Steven Sheldon"] +edition = "2018" description = "Rust smart pointers for Objective-C reference counting." keywords = ["objective-c", "osx", "ios"] diff --git a/objc_id/src/id.rs b/objc_id/src/id.rs index 2bb7a1aae..b5ed2829e 100644 --- a/objc_id/src/id.rs +++ b/objc_id/src/id.rs @@ -46,7 +46,7 @@ where { unsafe fn new(ptr: StrongPtr) -> Id { Id { - ptr: ptr, + ptr, item: PhantomData, own: PhantomData, } @@ -54,8 +54,11 @@ where /// Constructs an `Id` from a pointer to an unretained object and /// retains it. Panics if the pointer is null. - /// Unsafe because the pointer must be to a valid object and - /// the caller must ensure the ownership is correct. + /// + /// # Safety + /// + /// The pointer must be to a valid object and the caller must ensure the + /// ownership is correct. pub unsafe fn from_ptr(ptr: *mut T) -> Id { assert!( !ptr.is_null(), @@ -67,8 +70,11 @@ where /// Constructs an `Id` from a pointer to a retained object; this won't /// retain the pointer, so the caller must ensure the object has a +1 /// retain count. Panics if the pointer is null. - /// Unsafe because the pointer must be to a valid object and - /// the caller must ensure the ownership is correct. + /// + /// # Safety + /// + /// The pointer must be to a valid object and the caller must ensure the + /// ownership is correct. pub unsafe fn from_retained_ptr(ptr: *mut T) -> Id { assert!( !ptr.is_null(), @@ -125,10 +131,6 @@ where fn eq(&self, other: &Id) -> bool { self.deref() == other.deref() } - - fn ne(&self, other: &Id) -> bool { - self.deref() != other.deref() - } } impl Eq for Id where T: Eq {} @@ -149,13 +151,13 @@ impl fmt::Debug for Id where T: fmt::Debug, { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.deref().fmt(f) } } impl fmt::Pointer for Id { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.ptr, f) } } @@ -202,6 +204,7 @@ unsafe impl Send for WeakId where T: Sync {} mod tests { use super::{Id, ShareId, WeakId}; use objc::runtime::Object; + use objc::{class, msg_send}; fn retain_count(obj: &Object) -> usize { unsafe { msg_send![obj, retainCount] } diff --git a/objc_id/src/lib.rs b/objc_id/src/lib.rs index d61d4fe0c..2a82acf9a 100644 --- a/objc_id/src/lib.rs +++ b/objc_id/src/lib.rs @@ -12,8 +12,7 @@ which can be cloned to allow multiple references. Weak references may be created using the [`WeakId`](struct.WeakId.html) struct. ``` -# #[macro_use] extern crate objc; -# extern crate objc_id; +# use objc::msg_send; use objc::runtime::{Class, Object}; use objc_id::{Id, WeakId}; @@ -39,9 +38,6 @@ assert!(weak.load().is_none()); ``` */ -#[macro_use] -extern crate objc; - pub use id::{Id, Owned, Ownership, ShareId, Shared, WeakId}; mod id;