7 releases (1 stable)

Uses new Rust 2021

2.0.0-pre.0 Jun 13, 2022
2.0.0-beta.2 Jan 3, 2022
2.0.0-beta.1 Dec 22, 2021
2.0.0-beta.0 Nov 22, 2021
1.1.0 Nov 19, 2021

#96 in macOS and iOS APIs

Download history 27/week @ 2022-03-14 22/week @ 2022-03-21 8/week @ 2022-03-28 18/week @ 2022-04-04 7/week @ 2022-04-11 17/week @ 2022-04-18 41/week @ 2022-04-25 53/week @ 2022-05-02 17/week @ 2022-05-09 108/week @ 2022-05-16 37/week @ 2022-05-23 67/week @ 2022-05-30 27/week @ 2022-06-06 50/week @ 2022-06-13 21/week @ 2022-06-20 10/week @ 2022-06-27

121 downloads per month

MIT license

52KB
887 lines

objc2-encode

Latest version License Documentation CI

Objective-C type-encoding in Rust.

This crates provides the equivalent of the Objective-C @encode directive, and functions for comparing these encodings.

Additionally, it provides traits for annotating types that has an Objective-C encoding.

See the docs for a more thorough overview.

This crate is part of the objc2 project, see that for related crates.


lib.rs:

Objective-C type-encoding

This is re-exported into the top level of objc2.

The Objective-C directive @encode encodes types as strings, and this is used in various places in the runtime.

This crate provides the [Encoding] type to efficiently describe and compare these type-encodings.

Additionally it provides traits for annotating types that has an Objective-C encoding: Specifically [Encode] for structs, [RefEncode] for references and [EncodeArguments] for function arguments.

This crate is exported under the objc2 crate as objc2::encode, so usually you would just use it from there.

Example

Implementing [Encode] and [RefEncode] for a custom type:

use objc2_encode::{Encode, Encoding, RefEncode};
// or from objc2:
// use objc2::{Encode, Encoding, RefEncode};

#[repr(C)]
struct MyStruct {
    a: f32, // float
    b: i16, // int16_t
}

unsafe impl Encode for MyStruct {
    const ENCODING: Encoding<'static> = Encoding::Struct(
        "MyStruct", // Must use the same name as defined in C header files
        &[
            f32::ENCODING, // Same as Encoding::Float
            i16::ENCODING, // Same as Encoding::Short
        ],
    );
}

// @encode(MyStruct) -> "{MyStruct=fs}"
assert!(MyStruct::ENCODING.equivalent_to_str("{MyStruct=fs}"));

unsafe impl RefEncode for MyStruct {
    // Note that if `MyStruct` is an Objective-C instance, this should
    // be `Encoding::Object`.
    const ENCODING_REF: Encoding<'static> = Encoding::Pointer(&Self::ENCODING);
}

// @encode(MyStruct*) -> "^{MyStruct=fs}"
assert!(MyStruct::ENCODING_REF.equivalent_to_str("^{MyStruct=fs}"));

See the examples folder for more complex usage.

Caveats

We've taken the pragmatic approach with [Encode] and [RefEncode], and have implemented it for as many types as possible (instead of defining a bunch of subtraits for very specific purposes). However, that might sometimes be slightly surprising.

Notably we have implemented these for [bool], which, in reality, you would never actually see in an Objective-C method (they use BOOL, see objc2::runtime::Bool), but which can techincally occur, and as such does make sense to define an encoding for.

The other example is [()][unit], which doesn't make sense as a method argument, but is a very common return type, and hence implements Encode.

Further resources

No runtime deps