Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Argument-Label for Swift #156

Merged
merged 6 commits into from
Feb 5, 2023

Conversation

NiwakaDev
Copy link
Collaborator

This PR addresses #153 and introduces #[swift_bridge(label = "...")] to support Swift's Argument-Label.

Here's an example of using this:

// Rust
#[swift_bridge::bridge]
mod ffi {
    extern "Rust" {
        fn test_argument_label(
            #[swift_bridge(label = "someArg")] some_arg: i32,
            another_arg: i32,
        ) -> i32;
    }
}
// Swift 
XCTAssertEqual(test_argument_label(someArg: 10, 100), 110)

Copy link
Owner

@chinedufn chinedufn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NNNIIIICCCEEEE!!!!

Left some minor feedback but overall this is great. Awesome work!!!

@@ -92,6 +92,7 @@ pub(crate) struct ParsedExternFn {
pub args_into: Option<Vec<Ident>>,
/// Get one of the associated type's fields
pub get_field: Option<GetField>,
pub argument_labels: Option<HashMap<Ident, LitStr>>,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just HashMap<Ident, LitStr> instead of Option?

let value: LitStr = input.parse()?;
ArgumentAttr::ArgumentLabel(value)
}
_ => {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a UI test file for the unrecognized argument attribute error.

Similar to

//! # To Run
//! cargo test -p swift-bridge-macro -- ui trybuild=unrecognized-function-attribute.rs
#[swift_bridge::bridge]
mod ffi {
extern "Rust" {
#[swift_bridge(InvalidAttribute)]
fn some_function();
}
}
fn main() {}

error: Unrecognized attribute "InvalidAttribute".
--> tests/ui/unrecognized-function-attribute.rs:7:24
|
7 | #[swift_bridge(InvalidAttribute)]
| ^^^^^^^^^^^^^^^^

use crate::test_utils::parse_ok;
use quote::{format_ident, quote};

/// Verify that we can parse a function that has a argument label.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great test.

@@ -177,13 +177,17 @@ mod tests {

#[swift_bridge(return_into)]
fn some_function () -> Foo;

fn print_hello_world();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this? Seems like this should be removed?

}
}
};

let module = parse_ok(tokens);

assert!(module.functions[0].return_into);
assert_eq!(module.functions.len(), 2);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this? Seems like this should be removed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry...I usually add some test-codes to understand how swift-bridge works. I forgot to remove this. From now on, I'll remove them before sending a PR.

}
};

params.push(format!("_ {}", param))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can keep the push on the outside and just change it to params.push(param).

Then in the match block we can put the _ or the argument_label.

import XCTest
@testable import SwiftRustIntegrationTestRunner

/// Tests the #[swift_bridge(label = "someArg")] attribute.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/// Tests argument attributes such as `#[swift_bridge(label = "someArg")]`.

XCTAssertEqual(test_argument_label(someArg: 10, 100), 110)
}

func testPerformanceExample() throws {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can delete all of this setup and tear down and performance stuff. We never use them.

@chinedufn
Copy link
Owner

One more thing. We need to add docs.

Can put them under here

#### #[swift_bridge(args_into = (arg_name, another_arg_name))]
Used to name the arguments that should have `.into()` called on them when
passing them to their handler function.
One use case is for exposing a third-party type as a shared struct.
```rust
mod pretend_this_is_some_third_party_crate {
// We want to expose this third-party struct as a shared struct.
pub struct UniqueId {
id: u64
}
}
use pretend_this_is_some_third_party_crate::UniqueId;
fn a_function (_some_arg: UniqueId, _an_arg: UniqueId, _cool_arg: u8) {
// ...
}
mod ffi {
struct FfiUniqueId(u64);
extern "Rust" {
// super::a_function does not take a `u64` or an `FfiUniqueId`,
// but this still works since they both `impl Into<UniqueId>`.
#[swift_bridge(args_into = (some_arg, an_arg))]
fn a_function(some_arg: u64, an_arg: FfiUniqueId, cool_arg: u8);
}
}
impl From<u64> for UniqueId {
fn from(id: u64) -> UniqueId {
UniqueId {
id
}
}
}
impl Into<UniqueId> for ffi::FfiUniqueId {
fn into(self) -> UniqueId {
UniqueId(self.0)
}
}
```

let func_definition = match function.host_lang {
HostLang::Rust => {
gen_func_swift_calls_rust(function, &self.types, &self.swift_bridge_path)
let result =
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling this result makes it seem like we return a Result. Can we change this back?

@NiwakaDev
Copy link
Collaborator Author

Addressed your review! Please let me know if there are any omissions.

@chinedufn
Copy link
Owner

Thanks!

@chinedufn chinedufn merged commit 3c0d00d into chinedufn:master Feb 5, 2023
@chinedufn chinedufn mentioned this pull request Feb 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants