Skip to main content

ExpandReturnDecl

Struct ExpandReturnDecl 

Source
pub struct ExpandReturnDecl { /* private fields */ }
Expand description

Declares a type’s default output boundary: wherever the type is returned or handed to a callback, it is decomposed into this set of fields, all delivered in one FFI crossing — instead of an opaque handle the caller must then query field by field with more JNI calls. Applies to every function returning the type; a single function opts out or replaces the set via FunctionDecl::expand_return.

Build one with expand_return!, add fields with field / field_self, and hand it to the adapter’s expand declaration.

The type does not have to be declared in any package. A boundary decl on an undeclared type makes it rust-side-only: every returned / callback-delivered / Result-error value of it is decomposed into these fields and the value itself never reaches Kotlin. This is the natural shape for an error type consumed by the onError channel — no dead Kotlin class is emitted. Restrictions for such a type: field_self hard-errors (there is no Kotlin object to deliver), and field names cannot inherit from class members (there are none) — use .name(...) on each field or accept the camel-cased default.

// A returned Sample crosses as { payload, kind } in one call:
let _ = prebindgen_registry::expand_return!(Sample)
    .field(prebindgen_registry::fun!(sample_get_payload))
    .field(prebindgen_registry::fun!(sample_get_kind));

Implementations§

Source§

impl ExpandReturnDecl

Source

pub fn new(rust_type: Type) -> ExpandReturnDecl

Source

pub fn key(&self) -> &TypeKey

The type identity this declaration is registered under.

Source

pub fn rust_type(&self) -> &Origin<Type>

The type this declaration was written with, as originally parsed.

Source

pub fn field_list(&self) -> &[LocalField]

The declared field records, in declaration order. Named field_list rather than fields — that name is already the builder method that appends a value-form (Self::fields). pub(crate), not pubLocalField itself is pub(crate) (a public fn cannot return a private type).

Source

pub fn field(self, accessor: FunctionDecl) -> ExpandReturnDecl

Add one field — a reader whose value crosses as this leaf:

  • fun!(f) — a #[prebindgen] reader (f(&Self) -> Field), its signature read from the registry.
  • fun!(crate::f).sig(sig!((v: &Self) -> Field)) — a custom, locally-defined reader: any fn the binding crate defines, its signature stated (the receiver explicit — it must take &Self). One use among many: conditional delivery, an Option<&Self> return becoming a nullable handle leaf that is null when the binding-side predicate declines.

The Kotlin field name is uniform for both: an explicit .name(...) on the fun!; else the Kotlin name of the class member if the same fn is also declared as a method on this type’s class (so a getter that is both a method and a field is named once); else the camel-cased fn ident (a path’s LAST segment).

Only the accessor’s name is used here: expand overrides on the fun! are a hard error rather than a silent discard (the field’s own decomposition comes from ITS type’s boundary decl, not from the accessor).

Source

pub fn field_self(self) -> ExpandReturnDecl

Include the handle itself among the fields, so the consumer gets a live, closeable object in addition to the read-out values (e.g. a Query delivered with its fields and the handle it needs to reply). Declare it last, after any field that decomposes a nested handle, so the generated Rust moves the value only after those borrows.

Source

pub fn fields(self, decl: FieldsDecl) -> ExpandReturnDecl

Take the fields from the type’s value form — a #[prebindgen] accessor returning “this type’s own accessors gathered into one struct” — instead of restating them.

.fields(fields!(f)) is exactly .field(...) applied to each field of that struct, so it has the same configurability (per-field overrides and renames live on the FieldsDecl) and, crucially, the same decomposition rule: each field crosses by its own type’s default output boundary. A field whose type has its own expand_return! is decomposed by it (a KeyExpr field still crosses as its string, not as a handle); a declared data_class! field expands into its fields; a field behind Option / Vec stays one leaf. So swapping a hand-written field list for .fields(...) keeps the boundary shape it already had — what changes is that the list can no longer drift from the struct.

// Instead of restating SampleStruct's fields one by one:
let _ = prebindgen_registry::expand_return!(Sample)
    .fields(prebindgen_registry::fields!(sample_to_struct));

The accessor borrows its receiver (f(v: &Self) -> SelfStruct): the struct is built from a borrow, so each field is cloned into it and the leaves clone again out of it, and the value survives. It therefore mixes freely — .fields(...).field_self() delivers the value form’s fields and the live handle. At most one value form per decl.

Where the value is delivered owned — a callback argument (impl Fn(Sample)), an owned return — and nothing else needs it, use fields_self_into instead: those clones are being paid on a value that is about to be dropped.

Source

pub fn fields_self_into(self, decl: FieldsDecl) -> ExpandReturnDecl

Like fields, but the accessor consumes its receiver (f(v: Self) -> SelfStruct): the value is moved in and each field is moved out into its leaf. No clones at all.

This is the same decision field_self makes, one step further: .field_self() hands the value over whole, .fields_self_into(...) hands the value itself over as its parts, and .fields(...) hands over a copy of its parts. Use it wherever the value arrives owned and is not needed afterwards — the hot receive path this whole declarator exists to make cheap.

let _ = prebindgen_registry::expand_return!(Sample)
    .fields_self_into(prebindgen_registry::fields!(sample_into_struct));

Because it gives the value away it must be the decl’s only record — a .field_self() or a sibling .field(...) would read a value that is gone — which is a declaration-time panic either way round. It may still be reached through another value form: the parent’s field is handed to it by move, since a hoisted value form is an owned struct and its fields are disjoint.

The declarator and the accessor’s signature must agree; naming a &Self accessor here (or a by-value one on fields) is an error, so the declared intent cannot drift from the function it names. At a borrowed delivery position there is no value to give up, so the emitter clones once up front and consumes the clone — the same cost the borrowing form would have paid, which keeps one declaration usable by both owned and &T returns of the type.

Trait Implementations§

Source§

impl Clone for ExpandReturnDecl

Source§

fn clone(&self) -> ExpandReturnDecl

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl From<ExpandReturnDecl> for ExpandDecl

Source§

fn from(d: ExpandReturnDecl) -> ExpandDecl

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.