Rusty bindings for Apple libraries, brought to you by @NikolaiVazquez.
Doing so enables me to create high-quality open source software like this. ❤️
[dependencies.fruity] version = "0.2.0"
Each module for a library or framework has its own feature flag with the same name.
For example, this is how you enable the
[dependencies.fruity] version = "0.2.0" features = ["foundation"]
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.
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.
To make FFI safe and easy, the following Objective-C and Rust types are ABI-compatible:
NSObject * _Nonnulland
NSObject * _Nullableand
In Objective-C, methods take a pointer to where an
NSErroris 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.
Most of these types are classes that inherit from each other. Because true inheritance is not possible in Rust, Fruity uses
Derefto model Objective-C subclassing.
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_msgSendare always done with the correct object type, method selector, and arguments.
Getting a static class.
NSString::classretrieve the class directly through its symbol. This is instantaneous, especially when compared to calling into the Objective-C runtime via
NSStringfrom a Rust string literal.
ns_string!macro creates an
@"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!
selector!macro. See issue #2 for details.
Core types and traits of this crate.
Core Animation framework, also known as QuartzCore.
Core Audio framework.
Core Foundation framework.
Core Graphics framework.
Core Image framework.
Core Services framework.
Core Text framework.
Core Video framework.
System Configuration framework.