[][src]Trait uniffi::ViaFfi

pub unsafe trait ViaFfi: Sized {
    type FfiType;
    fn lower(self) -> Self::FfiType;
fn try_lift(v: Self::FfiType) -> Result<Self>;
fn write<B: BufMut>(&self, buf: &mut B);
fn try_read<B: Buf>(buf: &mut B) -> Result<Self>; }

Trait defining how to transfer values via the FFI layer.

The ViaFfi trait defines how to pass values of a particular type back-and-forth over the uniffi generated FFI layer, both as standalone argument or return values, and as part of serialized compound data structures.

(This trait is Like the InfoFfi trait from ffi_support, but local to this crate so that we can add some alternative implementations for different builtin types, and so that we can add support for receiving as well as returning).

Safety

This is an unsafe trait (implementing it requires unsafe impl) because we can't guarantee that it's safe to pass your type out to foreign-language code and back again. Buggy implementations of this trait might violate some assumptions made by the generated code, or might not match with the corresponding code in the generated foreign-language bindings.

In general, you should not need to implement this trait by hand, and should instead rely on implementations generated from your component IDL via the uniffi-bindgen scaffolding command.

Associated Types

type FfiType

The low-level type used for passing values of this type over the FFI.

This must be a C-compatible type (e.g. a numeric primitive, a #[repr(C)] struct) into which values of the target rust type can be converted.

For complex data types, we currently recommend using ffi_support::ByteBuffer and serializing the data for transfer. In theory it could be possible to build a matching #[repr(C)] struct for a complex data type and pass that instead, but explicit serialization is simpler and safer as a starting point.

Loading content...

Required methods

fn lower(self) -> Self::FfiType

Lower a rust value of the target type, into an FFI value of type Self::FfiType.

This trait method is used for sending data from rust to the foreign language code, by (hopefully cheaply!) converting it into someting that can be passed over the FFI and reconstructed on the other side.

Note that this method takes an owned self; this allows it to transfer ownership in turn to the foreign language code, e.g. by boxing the value and passing a pointer.

fn try_lift(v: Self::FfiType) -> Result<Self>

Lift a rust value of the target type, from an FFI value of type Self::FfiType.

This trait method is used for receiving data from the foreign language code in rust, by (hopefully cheaply!) converting it from a low-level FFI value of type Self::FfiType into a high-level rust value of the target type.

Since we cannot statically guarantee that the foreign-language code will send valid values of type Self::FfiType, this method is fallible.

fn write<B: BufMut>(&self, buf: &mut B)

Write a rust value into a bytebuffer, to send over the FFI in serialized form.

This trait method can be used for sending data from rust to the foreign language code, in cases where we're not able to use a special-purpose FFI type and must fall back to sending serialized bytes.

fn try_read<B: Buf>(buf: &mut B) -> Result<Self>

Read a rust value from a bytebuffer, received over the FFI in serialized form.

This trait method can be used for receiving data from the foreign language code in rust, in cases where we're not able to use a special-purpose FFI type and must fall back to receiving serialized bytes.

Since we cannot statically guarantee that the foreign-language code will send valid serialized bytes for the target type, this method is fallible.

Loading content...

Implementations on Foreign Types

impl ViaFfi for i8[src]

type FfiType = Self

impl ViaFfi for u8[src]

type FfiType = Self

impl ViaFfi for i16[src]

type FfiType = Self

impl ViaFfi for u16[src]

type FfiType = Self

impl ViaFfi for i32[src]

type FfiType = Self

impl ViaFfi for u32[src]

type FfiType = Self

impl ViaFfi for i64[src]

type FfiType = Self

impl ViaFfi for u64[src]

type FfiType = Self

impl ViaFfi for f32[src]

type FfiType = Self

impl ViaFfi for f64[src]

type FfiType = Self

impl ViaFfi for bool[src]

Support for passing boolean values via the FFI.

Booleans are passed as a u8 in order to avoid problems with handling C-compatible boolean values on JVM-based languages.

type FfiType = u8

impl<T: ViaFfi> ViaFfi for Option<T>[src]

Support for passing optional values via the FFI.

Optional values are currently always passed by serializing to a bytebuffer. We write either a zero byte for None, or a one byte followed by the containing item for Some.

In future we could do the same optimization as rust uses internally, where the None option is represented as a null pointer and the Some as a valid pointer, but that seems more fiddly and less safe in the short term, so it can wait.

type FfiType = ByteBuffer

impl<T: ViaFfi> ViaFfi for Vec<T>[src]

Support for passing vectors of values via the FFI.

Vectors are currently always passed by serializing to a bytebuffer. We write a u32 item count followed by each item in turn.

You can imagine a world where we pass some sort of (pointer, count) pair but that seems tremendously fiddly and unsafe in the short term. Maybe one day...

type FfiType = ByteBuffer

impl<V: ViaFfi> ViaFfi for HashMap<String, V>[src]

Support for associative arrays via the FFI. Note that because of webidl limitations, the key must always be of the String type.

HashMaps are currently always passed by serializing to a bytebuffer. We write a u32 entries count followed by each entry (string key followed by the value) in turn.

type FfiType = ByteBuffer

impl ViaFfi for String[src]

Support for passing Strings via the FFI.

Unlike many other implementations of ViaFfi, this passes a pointer rather than copying the data from one side to the other. This is a safety hazard, but turns out to be pretty nice for useability. This pointer *must be one owned by the rust allocator and it must point to valid utf-8 data (in other words, it must be an actual rust String).

When serialized in a bytebuffer, strings are represented as a u32 byte length followed by utf8-encoded bytes.

(In practice, we currently do end up copying the data, the copying just happens on the foreign language side rather than here in the rust code.)

type FfiType = *mut c_char

Loading content...

Implementors

Loading content...