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

arc_castable!, box_castable!, ref_castable! macros #404

Merged
merged 2 commits into from
Apr 19, 2024

Conversation

cpu
Copy link
Member

@cpu cpu commented Mar 30, 2024

Throughout the project we follow a pattern of implementing safe bridge types for FFI by:

  1. Creating a snake_case_named opaque struct.
  2. Implementing Castable for the struct:
    a. specifying a RustType (some native Rust type).
    b. specifying an Ownership (OwnershipBox, OwnershipArc, OwnershipRef).

In the case of OwnershipRef we may also need to add a PhantomData field referencing a lifetime to the opaque struct.

To reduce the boilerplate of doing all of the above over and over this commit adds three new macros (loosely inspired by the Rustls enum_builder! macro) that accomplish the task with less ceremony (as suggested in #151): arc_castable!, box_castable!, and ref_castable!.

Care has been taken to avoid the downside mentioned in 151 about rustdoc comments. The macros ensure the doc comments we add are associated with the correct type and not the macro itself. We can verify this fact by noting that the generated rustls.h header file that contains these comments has not changed with the introduction of the macros.

Existing instances of the pattern are updated to use these macros with one exception: the rustls_client_hello type implements Castable with OwnershipRef for rustls_client_hello<'a>, but it isn't the same opaque struct pattern as used elsewhere and so is best implemented by hand.

I've spot checked the expansion of the macros against my expectations and was happy with the results. If you want to do the same thing, here's a cargo expand of 10c5324.

Resolves #151

@cpu cpu self-assigned this Mar 30, 2024
///
/// If a lifetime is specified, the opaque struct will be parameterized by that lifetime
/// and a `PhantomData` field referencing the lifetime is added to the struct.
macro_rules! ref_castable {
Copy link
Member Author

Choose a reason for hiding this comment

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

I made an attempt to fold the implementation of ref_castable! into castable! so the bulk of the macro body could be shared like box_castable! and arc_castable! but I wasn't happy with the result and so went back to having this macro live on its own. I've only written a handful of simple macros so its possible someone with more experience could refactor this out.

@cpu cpu marked this pull request as draft April 2, 2024 14:21
@cpu cpu marked this pull request as ready for review April 2, 2024 15:43
Copy link
Collaborator

@jsha jsha left a comment

Choose a reason for hiding this comment

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

This is a really sweet improvement, thanks! Overall looks great, just some documentation / style nits.

src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/cipher.rs Outdated Show resolved Hide resolved
@cpu cpu force-pushed the cpu-castable-macros branch 2 times, most recently from dd01a1c to 7da8ff9 Compare April 19, 2024 15:09
@cpu cpu requested a review from jsha April 19, 2024 15:16
cpu added 2 commits April 19, 2024 13:55
`try_arc_from` became `clone_arc`.
Throughout the project we follow a pattern of:

1. Creating a `snake_case_named` opaque struct[0].
2. Implementing `Castable` for the struct:
  a. specifying a `RustType` (some native Rust type).
  b. specifying an `Ownership` (`OwnershipBox`, `OwnershipArc`, `OwnershipRef`).

In the case of `OwnershipRef` we may also need to add a `PhantomData`
field referencing a lifetime to the opaque struct.

To reduce the boilerplate of doing all of the above over and over this
commit adds three new macros that accomplish the task with less
ceremony:
  `arc_castable!`, `box_castable!`, and `ref_castable!`.

Existing instances of the pattern are updated to use these macros with
one exception: the `rustls_client_hello` type implements `Castable` with
`OwnershipRef` for `rustls_client_hello<'a>`, but it isn't the same
opaque struct pattern as used elsewhere and so is best implemented by
hand.

[0]: https://github.com/rustls/rustls-ffi/blob/main/CONTRIBUTING.md#opaque-struct-pattern
@cpu cpu merged commit d23891f into rustls:main Apr 19, 2024
23 checks passed
@cpu cpu deleted the cpu-castable-macros branch April 19, 2024 17:59
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.

Implement macro for opaque struct + CastPtr + BoxCastPtr
2 participants