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
impl ExpandReturnDecl
pub fn new(rust_type: Type) -> ExpandReturnDecl
Sourcepub fn rust_type(&self) -> &Origin<Type>
pub fn rust_type(&self) -> &Origin<Type>
The type this declaration was written with, as originally parsed.
Sourcepub fn field_list(&self) -> &[LocalField]
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 pub —
LocalField itself is pub(crate) (a public fn cannot return a
private type).
Sourcepub fn field(self, accessor: FunctionDecl) -> ExpandReturnDecl
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, anOption<&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).
Sourcepub fn field_self(self) -> ExpandReturnDecl
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.
Sourcepub fn fields(self, decl: FieldsDecl) -> ExpandReturnDecl
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.
Sourcepub fn fields_self_into(self, decl: FieldsDecl) -> ExpandReturnDecl
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
impl Clone for ExpandReturnDecl
Source§fn clone(&self) -> ExpandReturnDecl
fn clone(&self) -> ExpandReturnDecl
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl From<ExpandReturnDecl> for ExpandDecl
impl From<ExpandReturnDecl> for ExpandDecl
Source§fn from(d: ExpandReturnDecl) -> ExpandDecl
fn from(d: ExpandReturnDecl) -> ExpandDecl
Auto Trait Implementations§
impl !Send for ExpandReturnDecl
impl !Sync for ExpandReturnDecl
impl Freeze for ExpandReturnDecl
impl RefUnwindSafe for ExpandReturnDecl
impl Unpin for ExpandReturnDecl
impl UnsafeUnpin for ExpandReturnDecl
impl UnwindSafe for ExpandReturnDecl
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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