Skip to content

Commit 66c7ddf

Browse files
committed
Merge pull request #13 from madsmtm/documentation
Improve documentation
2 parents e846ef2 + fa2f1f9 commit 66c7ddf

40 files changed

+521
-278
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ members = [
44
"objc_encode",
55
"objc_exception",
66
"objc_foundation",
7+
"objc_foundation_derive",
78
"objc_id",
89
]
910
exclude = ["objc/tests-ios"]

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Objective-C in Rust
2+
3+
[![License](https://badgen.net/badge/license/MIT/blue)](../LICENSE.txt)
4+
[![CI Status](https://github.com/madsmtm/objc/workflows/CI/badge.svg)](https://github.com/madsmtm/objc/actions)

objc/Cargo.toml

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
[package]
22
name = "objc"
3-
version = "0.2.7"
4-
authors = ["Steven Sheldon"]
3+
version = "0.2.7" # Remember to update html_root_url in lib.rs
4+
authors = ["Steven Sheldon", "Mads Marquart <mads@marquart.dk>"]
55
edition = "2018"
66

7-
description = "Objective-C Runtime bindings and wrapper for Rust."
8-
keywords = ["objective-c", "osx", "ios", "cocoa", "uikit"]
7+
description = "Objective-C runtime bindings and interface."
8+
keywords = ["objective-c", "macos", "ios", "objc_msgSend"]
9+
categories = [
10+
"api-bindings",
11+
"development-tools::ffi",
12+
"os::macos-apis",
13+
]
914
readme = "README.md"
10-
repository = "http://github.com/SSheldon/rust-objc"
11-
documentation = "http://ssheldon.github.io/rust-objc/objc/"
15+
repository = "https://github.com/madsmtm/objc"
16+
documentation = "https://docs.rs/objc/"
1217
license = "MIT"
1318

1419
exclude = [
15-
".gitignore",
16-
".travis.yml",
1720
"doc.sh",
1821
"tests-ios/**",
1922
]

objc/README.md

+27-11
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
1-
Objective-C Runtime bindings and wrapper for Rust.
1+
# `objc`
2+
3+
[![Latest version](https://badgen.net/crates/v/objc)](https://crates.io/crates/objc)
4+
[![License](https://badgen.net/badge/license/MIT/blue)](../LICENSE.txt)
5+
[![Documentation](https://docs.rs/objc/badge.svg)](https://docs.rs/objc/)
6+
[![CI Status](https://github.com/madsmtm/objc/workflows/CI/badge.svg)](https://github.com/madsmtm/objc/actions)
27

3-
* Documentation: http://ssheldon.github.io/rust-objc/objc/
4-
* Crate: https://crates.io/crates/objc
8+
Objective-C Runtime bindings and wrapper for Rust.
59

610
## Messaging objects
711

812
Objective-C objects can be messaged using the `msg_send!` macro:
913

10-
``` rust
14+
```rust , no_run
15+
use objc::{class, msg_send};
16+
use objc::runtime::{BOOL, Object};
17+
1118
let cls = class!(NSObject);
12-
let obj: *mut Object = msg_send![cls, new];
13-
let hash: usize = msg_send![obj, hash];
14-
let is_kind: BOOL = msg_send![obj, isKindOfClass:cls];
15-
// Even void methods must have their return type annotated
16-
let _: () = msg_send![obj, release];
19+
unsafe {
20+
let obj: *mut Object = msg_send![cls, new];
21+
let hash: usize = msg_send![obj, hash];
22+
let is_kind: BOOL = msg_send![obj, isKindOfClass:cls];
23+
// Even void methods must have their return type annotated
24+
let _: () = msg_send![obj, release];
25+
}
1726
```
1827

1928
## Reference counting
@@ -24,7 +33,10 @@ A `StrongPtr` retains an object and releases the object when dropped.
2433
A `WeakPtr` will not retain the object, but can be upgraded to a `StrongPtr`
2534
and safely fails if the object has been deallocated.
2635

27-
``` rust
36+
```rust , no_run
37+
use objc::{class, msg_send};
38+
use objc::rc::{autoreleasepool, StrongPtr};
39+
2840
// StrongPtr will release the object when dropped
2941
let obj = unsafe {
3042
StrongPtr::new(msg_send![class!(NSObject), new])
@@ -52,7 +64,11 @@ methods can then be added before the class is ultimately registered.
5264
The following example demonstrates declaring a class named `MyNumber` that has
5365
one ivar, a `u32` named `_number` and a `number` method that returns it:
5466

55-
``` rust
67+
```rust , no_run
68+
use objc::{class, sel};
69+
use objc::declare::ClassDecl;
70+
use objc::runtime::{Object, Sel};
71+
5672
let superclass = class!(NSObject);
5773
let mut decl = ClassDecl::new("MyNumber", superclass).unwrap();
5874

examples/objc.rs objc/examples/introspection.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use objc::rc::StrongPtr;
22
use objc::runtime::{Class, Object};
3-
use objc::{class, msg_send, Encode};
3+
use objc::{class, msg_send, sel, Encode};
44

55
fn main() {
66
// Get a class

objc/src/cache.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ use core::sync::atomic::{AtomicPtr, Ordering};
44

55
use crate::runtime::{self, Class, Sel};
66

7-
/// Allows storing a `Sel` in a static and lazily loading it.
7+
/// Allows storing a [`Sel`] in a static and lazily loading it.
88
#[doc(hidden)]
99
pub struct CachedSel {
1010
ptr: AtomicPtr<c_void>,
1111
}
1212

1313
impl CachedSel {
14-
/// Constructs a new `CachedSel`.
14+
/// Constructs a new [`CachedSel`].
1515
pub const fn new() -> CachedSel {
1616
CachedSel {
1717
ptr: AtomicPtr::new(ptr::null_mut()),
@@ -35,14 +35,14 @@ impl CachedSel {
3535
}
3636
}
3737

38-
/// Allows storing a `Class` reference in a static and lazily loading it.
38+
/// Allows storing a [`Class`] reference in a static and lazily loading it.
3939
#[doc(hidden)]
4040
pub struct CachedClass {
4141
ptr: AtomicPtr<Class>,
4242
}
4343

4444
impl CachedClass {
45-
/// Constructs a new `CachedClass`.
45+
/// Constructs a new [`CachedClass`].
4646
pub const fn new() -> CachedClass {
4747
CachedClass {
4848
ptr: AtomicPtr::new(ptr::null_mut()),

objc/src/declare.rs

+40-31
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*!
22
Functionality for declaring Objective-C classes.
33
4-
Classes can be declared using the `ClassDecl` struct. Instance variables and
4+
Classes can be declared using the [`ClassDecl`] struct. Instance variables and
55
methods can then be added before the class is ultimately registered.
66
77
# Example
@@ -13,7 +13,6 @@ one ivar, a `u32` named `_number` and a `number` method that returns it:
1313
# use objc::{class, sel};
1414
# use objc::declare::ClassDecl;
1515
# use objc::runtime::{Class, Object, Sel};
16-
# fn main() {
1716
let superclass = class!(NSObject);
1817
let mut decl = ClassDecl::new("MyNumber", superclass).unwrap();
1918
@@ -30,7 +29,6 @@ unsafe {
3029
}
3130
3231
decl.register();
33-
# }
3432
```
3533
*/
3634

@@ -52,7 +50,7 @@ pub trait MethodImplementation {
5250
/// The argument types of the method.
5351
type Args: EncodeArguments;
5452

55-
/// Returns self as an `Imp` of a method.
53+
/// Returns self as an [`Imp`] of a method.
5654
fn imp(self) -> Imp;
5755
}
5856

@@ -129,20 +127,21 @@ impl ClassDecl {
129127
}
130128
}
131129

132-
/// Constructs a `ClassDecl` with the given name and superclass.
133-
/// Returns `None` if the class couldn't be allocated.
130+
/// Constructs a [`ClassDecl`] with the given name and superclass.
131+
///
132+
/// Returns [`None`] if the class couldn't be allocated.
134133
pub fn new(name: &str, superclass: &Class) -> Option<ClassDecl> {
135134
ClassDecl::with_superclass(name, Some(superclass))
136135
}
137136

138137
/**
139-
Constructs a `ClassDecl` declaring a new root class with the given name.
140-
Returns `None` if the class couldn't be allocated.
138+
Constructs a [`ClassDecl`] declaring a new root class with the given name.
139+
Returns [`None`] if the class couldn't be allocated.
141140
142141
An implementation for `+initialize` must also be given; the runtime calls
143142
this method for all classes, so it must be defined on root classes.
144143
145-
Note that implementing a root class is not a simple endeavor.
144+
Note that implementing a root class is not a simple endeavor!
146145
For example, your class probably cannot be passed to Cocoa code unless
147146
the entire `NSObject` protocol is implemented.
148147
Functionality it expects, like implementations of `-retain` and `-release`
@@ -158,9 +157,12 @@ impl ClassDecl {
158157
decl
159158
}
160159

161-
/// Adds a method with the given name and implementation to self.
162-
/// Panics if the method wasn't sucessfully added
163-
/// or if the selector and function take different numbers of arguments.
160+
/// Adds a method with the given name and implementation.
161+
///
162+
/// # Panics
163+
///
164+
/// Panics if the method wasn't sucessfully added or if the selector and
165+
/// function take different numbers of arguments.
164166
///
165167
/// # Safety
166168
///
@@ -184,9 +186,12 @@ impl ClassDecl {
184186
assert!(success != NO, "Failed to add method {:?}", sel);
185187
}
186188

187-
/// Adds a class method with the given name and implementation to self.
188-
/// Panics if the method wasn't sucessfully added
189-
/// or if the selector and function take different numbers of arguments.
189+
/// Adds a class method with the given name and implementation.
190+
///
191+
/// # Panics
192+
///
193+
/// Panics if the method wasn't sucessfully added or if the selector and
194+
/// function take different numbers of arguments.
190195
///
191196
/// # Safety
192197
///
@@ -211,12 +216,12 @@ impl ClassDecl {
211216
assert!(success != NO, "Failed to add class method {:?}", sel);
212217
}
213218

214-
/// Adds an ivar with type `T` and the provided name to self.
215-
/// Panics if the ivar wasn't successfully added.
216-
pub fn add_ivar<T>(&mut self, name: &str)
217-
where
218-
T: Encode,
219-
{
219+
/// Adds an ivar with type `T` and the provided name.
220+
///
221+
/// # Panics
222+
///
223+
/// If the ivar wasn't successfully added.
224+
pub fn add_ivar<T: Encode>(&mut self, name: &str) {
220225
let c_name = CString::new(name).unwrap();
221226
let encoding = CString::new(T::ENCODING.to_string()).unwrap();
222227
let size = mem::size_of::<T>();
@@ -227,15 +232,18 @@ impl ClassDecl {
227232
assert!(success != NO, "Failed to add ivar {}", name);
228233
}
229234

230-
/// Adds a protocol to self. Panics if the protocol wasn't successfully
231-
/// added
235+
/// Adds the given protocol to self.
236+
///
237+
/// # Panics
238+
///
239+
/// If the protocol wasn't successfully added.
232240
pub fn add_protocol(&mut self, proto: &Protocol) {
233241
let success = unsafe { runtime::class_addProtocol(self.cls, proto) };
234242
assert!(success != NO, "Failed to add protocol {:?}", proto);
235243
}
236244

237-
/// Registers self, consuming it and returning a reference to the
238-
/// newly registered `Class`.
245+
/// Registers the [`ClassDecl`], consuming it, and returns a reference to
246+
/// the newly registered [`Class`].
239247
pub fn register(self) -> &'static Class {
240248
unsafe {
241249
let cls = self.cls;
@@ -262,8 +270,9 @@ pub struct ProtocolDecl {
262270
}
263271

264272
impl ProtocolDecl {
265-
/// Constructs a `ProtocolDecl` with the given name. Returns `None` if the
266-
/// protocol couldn't be allocated.
273+
/// Constructs a [`ProtocolDecl`] with the given name.
274+
///
275+
/// Returns [`None`] if the protocol couldn't be allocated.
267276
pub fn new(name: &str) -> Option<ProtocolDecl> {
268277
let c_name = CString::new(name).unwrap();
269278
let proto = unsafe { runtime::objc_allocateProtocol(c_name.as_ptr()) };
@@ -303,7 +312,7 @@ impl ProtocolDecl {
303312
}
304313
}
305314

306-
/// Adds an instance method declaration with a given description to self.
315+
/// Adds an instance method declaration with a given description.
307316
pub fn add_method_description<Args, Ret>(&mut self, sel: Sel, is_required: bool)
308317
where
309318
Args: EncodeArguments,
@@ -312,7 +321,7 @@ impl ProtocolDecl {
312321
self.add_method_description_common::<Args, Ret>(sel, is_required, true)
313322
}
314323

315-
/// Adds a class method declaration with a given description to self.
324+
/// Adds a class method declaration with a given description.
316325
pub fn add_class_method_description<Args, Ret>(&mut self, sel: Sel, is_required: bool)
317326
where
318327
Args: EncodeArguments,
@@ -328,8 +337,8 @@ impl ProtocolDecl {
328337
}
329338
}
330339

331-
/// Registers self, consuming it and returning a reference to the
332-
/// newly registered `Protocol`.
340+
/// Registers the [`ProtocolDecl`], consuming it and returning a reference
341+
/// to the newly registered [`Protocol`].
333342
pub fn register(self) -> &'static Protocol {
334343
unsafe {
335344
runtime::objc_registerProtocol(self.proto);

objc/src/encode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ unsafe impl<'a> Encode for &'a mut Class {
2222
}
2323

2424
/// Types that represent a group of arguments, where each has an Objective-C
25-
/// type encoding.
25+
/// type-encoding.
2626
pub trait EncodeArguments {
2727
/// The type as which the encodings for Self will be returned.
2828
const ENCODINGS: &'static [Encoding<'static>];

objc/src/exception.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use objc_exception;
2-
31
use crate::rc::StrongPtr;
42
use crate::runtime::Object;
53

@@ -14,11 +12,12 @@ use crate::runtime::Object;
1412
///
1513
/// # Safety
1614
///
17-
/// This encourages unwinding through the closure from Objective-C, which is
18-
/// not safe.
19-
pub unsafe fn catch_exception<F, R>(closure: F) -> Result<R, StrongPtr>
20-
where
21-
F: FnOnce() -> R,
22-
{
15+
/// The given closure must not panic.
16+
///
17+
/// Additionally, this unwinds through the closure from Objective-C, which is
18+
/// undefined behaviour until `C-unwind` is stabilized, see [RFC-2945].
19+
///
20+
/// [RFC-2945]: https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html
21+
pub unsafe fn catch_exception<R>(closure: impl FnOnce() -> R) -> Result<R, StrongPtr> {
2322
objc_exception::r#try(closure).map_err(|exception| StrongPtr::new(exception as *mut Object))
2423
}

objc/src/lib.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ Objective-C objects can be messaged using the [`msg_send!`](macro.msg_send!.html
88
``` no_run
99
# use objc::{class, msg_send};
1010
# use objc::runtime::{BOOL, Class, Object};
11-
# fn main() {
1211
# unsafe {
1312
let cls = class!(NSObject);
1413
let obj: *mut Object = msg_send![cls, new];
@@ -17,7 +16,6 @@ let is_kind: BOOL = msg_send![obj, isKindOfClass:cls];
1716
// Even void methods must have their return type annotated
1817
let _: () = msg_send![obj, release];
1918
# }
20-
# }
2119
```
2220
2321
# Reference counting
@@ -63,10 +61,20 @@ The bindings can be used on Linux or *BSD utilizing the
6361
#![no_std]
6462
#![warn(missing_docs)]
6563
#![allow(clippy::missing_safety_doc)]
64+
// Update in Cargo.toml as well.
65+
#![doc(html_root_url = "https://docs.rs/objc/0.2.7")]
6666

6767
extern crate alloc;
6868
extern crate std;
6969

70+
#[cfg(doctest)]
71+
#[doc = include_str!("../README.md")]
72+
extern "C" {}
73+
74+
#[cfg(doctest)]
75+
#[doc = include_str!("../../README.md")]
76+
extern "C" {}
77+
7078
pub use objc_encode::{Encode, Encoding};
7179

7280
pub use crate::encode::EncodeArguments;

0 commit comments

Comments
 (0)