From 5a1682b8f69cb2cdf0b089d4d4aa1a0cce604aec Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 20 Aug 2024 16:33:29 -0700 Subject: [PATCH] mention Option in docs --- src/option.md | 32 ++++++++++++++++++++++++++------ src/types.md | 8 +++++--- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/option.md b/src/option.md index cda2135..c0ef074 100644 --- a/src/option.md +++ b/src/option.md @@ -2,7 +2,7 @@ Option types in Diplomat are relatively straightforward, you simply use `Option` and it turns into the idiomatic equivalent over FFI. -`Option` currently only works when wrapping reference types (`Box` and `&OpaqueType`), or in return type position: +`Option` currently only works when wrapping reference types (`Box` and `&OpaqueType`), wrapping structs/enums/primitives, or in return type position: ```rust #[diplomat::bridge] @@ -16,9 +16,8 @@ mod ffi { Some(Box::new(Thingy)) } - // works in return position, but not elsewhere - pub fn make_option() -> Option { - Some(1) + pub fn increment_option(x: Option) -> Option { + x.map(|inner| inner + 1) } } } @@ -26,7 +25,28 @@ mod ffi { In C++ `maybe_create` will return a `std::optional>`, and in JS it will return a potentially-null object. -`make_option` will have similar behavior, returning `std::optional` and an integer-or-null in JS. +`make_option` will have similar behavior, returning `std::optional` and an integer-or-null in JS. It will accept `std::optional` in C++ and null-check the parameter in JS. +## DiplomatOption -In the future, `Option` will be supported for most types `T` ([#246](https://github.com/rust-diplomat/diplomat/issues/246)). \ No newline at end of file +`Option` is FFI-safe for reference types but not for other arbitrary types. When used in function parameters, Diplomat will automatically use FFI-safe types over the boundary, however with structs layout concerns prevent automatically doing this. Instead, if you wish to use an `Option` in a struct (for struct, enum, or primitive `T`), use `DiplomatOption` + +```rust +#[diplomat::bridge] +mod ffi { + use diplomat_runtime::DiplomatOption; + + #[diplomat::opaque] + pub struct MyOpaque(u8); + + pub enum MyEnum { + Foo, Bar + } + + pub struct MyStruct<'a> { + a: DiplomatOption, + b: DiplomatOption, + c: Option<&'a MyOpaque> + } +} +``` \ No newline at end of file diff --git a/src/types.md b/src/types.md index 36bd1de..f830187 100644 --- a/src/types.md +++ b/src/types.md @@ -18,13 +18,15 @@ Diplomat only supports a small set of types that can be passed over FFI. - `&DiplomatStr`: An unvalidated string expected to be UTF-8. - `&DiplomatStr16`: An unvalidated string expected to be UTF-16. - [`DiplomatWriteable`](./writeable.md) for returning strings. This needs to be the last parameter of the method. - - [`Option<&T>` ,`Option>`](./option.md) of opaque types - - [`Result` and `Option`](./result.md) in return values + - [`Option<&T>` ,`Option>`](./option.md) of opaque types, `Option` of structs, enums, and primitives + - [`Option<&T>` ,`Option>`](./option.md) of opaque types, `Option` of structs, enums, and primitives + - Callbacks in parameters (Undocumented in the book, but implemented in C and Kotlin. See [tracking issue](https://github.com/rust-diplomat/diplomat/issues/146)) + - [`Result` in return values - `()` as a `Result` `Ok`/`Error` type, or as a return value - Custom types - Custom [opaque types](./opaque.md) (passed as references or via `Box`) - Custom [structs and C-like enums](./structs.md) -More types can be supported in the future (We have issues for [callbacks](https://github.com/rust-diplomat/diplomat/issues/146) and [full option types](https://github.com/rust-diplomat/diplomat/issues/246)) +More types can be supported in the future (We have issues for [callbacks](https://github.com/rust-diplomat/diplomat/issues/146) and [traits](https://github.com/rust-diplomat/diplomat/pull/621)) The _main_ distinction to keep track of is between "opaque types" and "structs": opaque types are for when you want to wrap a Rust object that has its own semantics, whereas "structs" are for when you want to transparently pass around multiple values at once (usually when you want to make an options struct as an argument, or return multiple values at once).