Skip to content

Commit

Permalink
Merge pull request #1 from madsmtm/workspace
Browse files Browse the repository at this point in the history
Move crates into a cargo workspace
  • Loading branch information
madsmtm authored Aug 29, 2021
2 parents c8696b0 + 8fc1393 commit a021c4c
Show file tree
Hide file tree
Showing 61 changed files with 2,698 additions and 34 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
doc/
target/
Cargo.lock

Expand Down
41 changes: 8 additions & 33 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,33 +1,8 @@
[package]
name = "objc"
version = "0.2.7"
authors = ["Steven Sheldon"]
edition = "2018"

description = "Objective-C Runtime bindings and wrapper for Rust."
keywords = ["objective-c", "osx", "ios", "cocoa", "uikit"]
readme = "README.md"
repository = "http://github.com/SSheldon/rust-objc"
documentation = "http://ssheldon.github.io/rust-objc/objc/"
license = "MIT"

exclude = [
".gitignore",
".travis.yml",
"doc.sh",
"travis_install.sh",
"travis_test.sh",
"tests-ios/**",
]

[features]
exception = ["objc_exception"]
verify_message = []

[dependencies]
malloc_buf = "1.0"
objc-encode = "1.0"

[dependencies.objc_exception]
version = "0.1"
optional = true
[workspace]
members = [
"objc",
"objc_encode",
"objc_exception",
"objc_foundation",
"objc_id",
]
File renamed without changes.
File renamed without changes.
30 changes: 30 additions & 0 deletions objc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[package]
name = "objc"
version = "0.2.7"
authors = ["Steven Sheldon"]
edition = "2018"

description = "Objective-C Runtime bindings and wrapper for Rust."
keywords = ["objective-c", "osx", "ios", "cocoa", "uikit"]
readme = "README.md"
repository = "http://github.com/SSheldon/rust-objc"
documentation = "http://ssheldon.github.io/rust-objc/objc/"
license = "MIT"

exclude = [
".gitignore",
".travis.yml",
"doc.sh",
"travis_install.sh",
"travis_test.sh",
"tests-ios/**",
]

[features]
exception = ["objc_exception"]
verify_message = []

[dependencies]
malloc_buf = "1.0"
objc-encode = { path = "../objc_encode", version = "1.0" }
objc_exception = { path = "../objc_exception", version = "0.1", optional = true }
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
17 changes: 17 additions & 0 deletions objc_encode/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "objc-encode"
version = "1.1.0"
authors = ["Steven Sheldon"]
edition = "2018"

description = "Objective-C type encoding creation and parsing in Rust."
keywords = ["objective-c", "osx", "ios", "cocoa", "uikit"]
categories = ["development-tools::ffi", "no-std"]
readme = "README.md"
repository = "http://github.com/SSheldon/rust-objc-encode"
documentation = "http://ssheldon.github.io/rust-objc/objc_encode/"
license = "MIT"

exclude = [
".gitignore",
]
38 changes: 38 additions & 0 deletions objc_encode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Objective-C type encoding creation and parsing in Rust.

The Objective-C compiler encodes types as strings for usage in the runtime.
This crate aims to provide a strongly-typed (rather than stringly-typed) way
to create and describe these type encodings without memory allocation in Rust.

# Implementing Encode

This crate declares an `Encode` trait that can be implemented for types that
the Objective-C compiler can encode. Implementing this trait looks like:

``` rust
unsafe impl Encode for CGPoint {
const ENCODING: Encoding<'static> =
Encoding::Struct("CGPoint", &[CGFloat::ENCODING, CGFLOAT::ENCODING]);
}
```

For an example of how this works with more complex types, like structs
containing structs, see the `core_graphics` example.

# Comparing with encoding strings

An `Encoding` can be compared with an encoding string from the Objective-C
runtime:

``` rust
assert!(&i32::ENCODING == "i");
```

# Generating encoding strings

Every `Encoding` implements `Display` as its string representation.
This can be generated conveniently through the `to_string` method:

``` rust
assert_eq!(i32::ENCODING.to_string(), "i");
```
46 changes: 46 additions & 0 deletions objc_encode/examples/core_graphics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
extern crate objc_encode;

use objc_encode::{Encode, Encoding};

#[cfg(target_pointer_width = "32")]
type CGFloat = f32;

#[cfg(target_pointer_width = "64")]
type CGFloat = f64;

#[repr(C)]
struct CGPoint {
x: CGFloat,
y: CGFloat,
}

unsafe impl Encode for CGPoint {
const ENCODING: Encoding<'static> =
Encoding::Struct("CGPoint", &[CGFloat::ENCODING, CGFloat::ENCODING]);
}

#[repr(C)]
struct CGSize {
width: CGFloat,
height: CGFloat,
}

unsafe impl Encode for CGSize {
const ENCODING: Encoding<'static> =
Encoding::Struct("CGSize", &[CGFloat::ENCODING, CGFloat::ENCODING]);
}

#[repr(C)]
struct CGRect {
origin: CGPoint,
size: CGSize,
}

unsafe impl Encode for CGRect {
const ENCODING: Encoding<'static> =
Encoding::Struct("CGRect", &[CGPoint::ENCODING, CGSize::ENCODING]);
}

fn main() {
println!("{}", CGRect::ENCODING);
}
103 changes: 103 additions & 0 deletions objc_encode/src/encode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use core::ffi::c_void;

use crate::Encoding;

/// Types that have an Objective-C type encoding.
///
/// Unsafe because Objective-C will make assumptions about the type (like its
/// size and alignment) from its encoding, so the implementer must verify that
/// the encoding is accurate.
pub unsafe trait Encode {
/// Returns the Objective-C type encoding for Self.
const ENCODING: Encoding<'static>;
}

macro_rules! encode_impls {
($($t:ty : $e:ident,)*) => ($(
unsafe impl Encode for $t {
const ENCODING: Encoding<'static> = Encoding::$e;
}
)*);
}

encode_impls!(
i8: Char,
i16: Short,
i32: Int,
i64: LongLong,
u8: UChar,
u16: UShort,
u32: UInt,
u64: ULongLong,
f32: Float,
f64: Double,
bool: Bool,
(): Void,
*mut i8: String,
*const i8: String,
*mut u8: String,
*const u8: String,
);

unsafe impl Encode for isize {
#[cfg(target_pointer_width = "32")]
const ENCODING: Encoding<'static> = i32::ENCODING;

#[cfg(target_pointer_width = "64")]
const ENCODING: Encoding<'static> = i64::ENCODING;
}

unsafe impl Encode for usize {
#[cfg(target_pointer_width = "32")]
const ENCODING: Encoding<'static> = u32::ENCODING;

#[cfg(target_pointer_width = "64")]
const ENCODING: Encoding<'static> = u64::ENCODING;
}

unsafe impl Encode for *mut c_void {
const ENCODING: Encoding<'static> = Encoding::Pointer(&Encoding::Void);
}

unsafe impl Encode for *const c_void {
const ENCODING: Encoding<'static> = Encoding::Pointer(&Encoding::Void);
}

// TODO: Replace this with a const generics implementation when they stabilise (#44580)
macro_rules! slice_encode_impl {
($($n:literal),* $(,)?) => {
$(
unsafe impl<T: Encode> Encode for [T; $n] {
const ENCODING: Encoding<'static> = Encoding::Array($n, &<T as Encode>::ENCODING);
}
)*
};
}

slice_encode_impl!(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32
);

/*
External crates cannot implement Encode for pointers or Optionals, but they
*can* implement it for references. rust-lang/rust#25126
As a workaround, we provide implementations for these types that return the
same encoding as references.
*/
unsafe impl<T> Encode for *const T where for<'b> &'b T: Encode {
const ENCODING: Encoding<'static> = <&T>::ENCODING;
}

unsafe impl<T> Encode for *mut T where for<'b> &'b mut T: Encode {
const ENCODING: Encoding<'static> = <&mut T>::ENCODING;
}

unsafe impl<'a, T> Encode for Option<&'a T> where for<'b> &'b T: Encode {
const ENCODING: Encoding<'static> = <&T>::ENCODING;
}

unsafe impl<'a, T> Encode for Option<&'a mut T> where for<'b> &'b mut T: Encode {
const ENCODING: Encoding<'static> = <&mut T>::ENCODING;
}
Loading

0 comments on commit a021c4c

Please sign in to comment.