Expand description
Rusty bindings for Apple libraries, brought to you by @NikolaiVazquez.
§Index
§Donate
If this project is useful to you, consider sponsoring me or donating directly!
Doing so enables me to create high-quality open source software like this. ❤️
§Usage
This library is available on crates.io and can be used in your
project by adding the following to your project’s Cargo.toml
:
[dependencies.fruity]
version = "0.3.0"
§Feature Flags
Each module for a library or framework has its own feature flag with the same name.
For example, this is how you enable the foundation
module:
[dependencies.fruity]
version = "0.3.0"
features = ["foundation"]
This feature transitively enables the objc
and core_graphics
features/modules.
§Goals
§Idiomatic Rust
Fruity makes interfacing with these C and Objective-C APIs feel natural in Rust.
-
Automatic Reference Counting.
Fruity takes advantage of Rust’s ownership model to handle object reference counting for you.
NSObject
is a smart pointer that callsretain
onClone
andrelease
onDrop
. This is exactly how Rust’sArc<T>
works. -
Option<NSObject>
.In Objective-C, all objects are nullable unless marked with
_Nonnull
. This often leads to either very defensive checks or careless ignoring of null objects.Fruity reverses that and instead makes all objects (such as
NSObject
) non-null by default. An object can be made nullable by wrapping it withOption<T>
.To make FFI safe and easy, the following Objective-C and Rust types are ABI-compatible:
-
NSObject * _Nonnull
andNSObject
-
NSObject * _Nullable
andOption<NSObject>
This is because
NSObject
is a#[repr(transparent)]
wrapper around aNonNull<T>
pointer. -
-
Result<T, NSError>
.In Objective-C, methods take a pointer to where an
NSError
is placed upon failure. This makes it easy to avoid error handling and assume the happy path, which can lead to bugs when errors occur.Fruity instead returns a
Result
, which is the canonical way to handle errors in Rust. This ensures that errors must be acknowledged in some way. -
Natural inheritance.
Most of these types are classes that inherit from each other. Because true inheritance is not possible in Rust, Fruity uses
Deref
to model Objective-C subclassing.
§Zero Cost
Using Fruity to interface with Objective-C libraries should have as little runtime cost as writing the same code directly in Objective-C.
This is true for the following:
-
Calling object methods.
Method dispatch is always direct and does not need the error checking overhead of other wrappers that use the
objc::msg_send!
macro. This also reduces the size of your program by not emitting panics that would otherwise never get called.This library is carefully written to ensure that calls to
objc_msgSend
are always done with the correct object type, method selector, and arguments. -
Getting a static class.
Getters like
NSString::class
retrieve the class directly through its symbol. This is instantaneous, especially when compared to calling into the Objective-C runtime viaobjc_getClass
. -
Creating an
NSString
from a Rust string literal.The
ns_string!
macro creates anNSString
literal (i.e.@"string"
) at compile time. There is no runtime dispatch/allocation/initialization cost.
Some parts of this library are still not zero cost. Your help would be much appreciated here!
These are:
- The
selector!
macro. See issue #2 for details.
§License
This project is released under either the MIT License or Apache License (Version 2.0), at your choosing.
Modules§
- app_kit
- AppKit framework.
- cf_
network - CFNetwork framework.
- core
- Core types and traits of this crate.
- core_
animation - Core Animation framework, also known as QuartzCore.
- core_
audio - Core Audio framework.
- core_
foundation - Core Foundation framework.
- core_
graphics - Core Graphics framework.
- core_
image - Core Image framework.
- core_
services - Core Services framework.
- core_
text - Core Text framework.
- core_
video - Core Video framework.
- dispatch
- Dispatch library.
- foundation
- Foundation framework.
- io_kit
- IOKit framework.
- objc
- Objective-C library.
- system_
configuration - System Configuration framework.
Macros§
- ns_
string - Creates an
NSString
from a static string. - objc_
class - Returns a
Class
reference with the given name. - selector
- Creates a
Sel
from a selector literal. - selector_
str - Creates a
&'static str
from a selector literal, that may be used as the basis of aSel
.