Struct abi_stable::sabi_trait::RObject[][src]

#[repr(C)]
pub struct RObject<'lt, P, I, V> where
    P: GetPointerKind
{ /* fields omitted */ }
Expand description

RObject implements ffi-safe trait objects, for a minimal selection of traits.

The main use of RObject<_> is as the default backend for #[sabi_trait] generated trait objects.

Construction

RObject<_> is how #[sabi_trait]-based ffi-safe trait objects are implemented, and there’s no way to construct it separate from those.

Trait object

RObject<'borrow, Pointer<()>, Interface, VTable> can be used as a trait object for any combination of the traits listed below:

  • Send

  • Sync

  • Debug

  • Display

  • Error

  • Clone

Deconstruction

RObject<_> can be unwrapped into a concrete type, within the same dynamic library/executable that constructed it, using these (fallible) conversion methods:

RObject can only be converted back if the trait object was constructed to allow it.

Implementations

Constructs an RObject from a pointer and an extra vtable.

This is mostly intended to be called by #[sabi_trait] generated trait objects.

Safety

These are the requirements for the caller:

  • P must be a pointer to the type that the vtable functions take as the first parameter.

  • The vtable must not come from a reborrowed RObject (created using RObject::reborrow or RObject::reborrow_mut).

  • The vtable must be the SomeVTableName of a struct declared with #[derive(StableAbi)] #[sabi(kind(Prefix(prefix_ref="SomeVTableName")))].

  • The vtable must have RObjectVtable_Ref as its first declared field

This function allows constructing an RObject in a constant/static.

This is mostly intended for #[sabi_trait] generated trait objects

Safety

This has the same safety requirements as RObject::with_vtable

Example

Because this is intended for #[sabi_trait] generated trait objects, this demonstrates how to construct one in a constant.

use abi_stable::sabi_trait::{
    doc_examples::{ConstExample_CTO, ConstExample_MV},
    prelude::TD_Opaque,
};

const EXAMPLE0: ConstExample_CTO<'static, 'static> =
    ConstExample_CTO::from_const(&0usize, TD_Opaque, ConstExample_MV::VTABLE);

Attempts to unerase this trait object into the pointer it was constructed with.

Errors

This will return an error in any of these conditions:

  • It is called in a dynamic library/binary outside the one from which this RObject was constructed.

  • The trait object wrapping this RObject was constructed with a TD_CanDowncast argument.

  • T is not the concrete type this RObject<_> was constructed with.

Example
use abi_stable::{
    sabi_trait::doc_examples::Doer_TO, std_types::RBox,
    type_level::downcasting::TD_CanDowncast,
};

let to = || Doer_TO::from_value(5usize, TD_CanDowncast);

// `to.obj` is an RObject
assert_eq!(
    to().obj.downcast_into::<usize>().ok(),
    Some(RBox::new(5usize))
);
assert_eq!(to().obj.downcast_into::<u8>().ok(), None);

Attempts to unerase this trait object into a reference of the value was constructed with.

Errors

This will return an error in any of these conditions:

  • It is called in a dynamic library/binary outside the one from which this RObject was constructed.

  • The trait object wrapping this RObject was constructed with a TD_CanDowncast argument.

  • T is not the concrete type this RObject<_> was constructed with.

Example
use abi_stable::{
    sabi_trait::doc_examples::Doer_TO, std_types::RArc,
    type_level::downcasting::TD_CanDowncast, RMut, RRef,
};

{
    let to: Doer_TO<'_, RArc<()>> =
        Doer_TO::from_ptr(RArc::new(8usize), TD_CanDowncast);

    // `to.obj` is an RObject
    assert_eq!(to.obj.downcast_as::<usize>().ok(), Some(&8usize));
    assert_eq!(to.obj.downcast_as::<u8>().ok(), None);
}
{
    // `#[sabi_trait]` trait objects constructed from `&`
    // use `RRef<'_, ()>` instead of `&'_ ()`
    // since `&T` can't soundly be transmuted back and forth into `&()`
    let to: Doer_TO<'_, RRef<'_, ()>> = Doer_TO::from_ptr(&13usize, TD_CanDowncast);

    assert_eq!(to.obj.downcast_as::<usize>().ok(), Some(&13usize));
    assert_eq!(to.obj.downcast_as::<u8>().ok(), None);
}
{
    let mmut = &mut 21usize;
    // `#[sabi_trait]` trait objects constructed from `&mut`
    // use `RMut<'_, ()>` instead of `&'_ mut ()`
    // since `&mut T` can't soundly be transmuted back and forth into `&mut ()`
    let to: Doer_TO<'_, RMut<'_, ()>> = Doer_TO::from_ptr(mmut, TD_CanDowncast);

    assert_eq!(to.obj.downcast_as::<usize>().ok(), Some(&21usize));
    assert_eq!(to.obj.downcast_as::<u8>().ok(), None);
}

Attempts to unerase this trait object into a mutable reference of the value was constructed with.

Errors

This will return an error in any of these conditions:

  • It is called in a dynamic library/binary outside the one from which this RObject was constructed.

  • The trait object wrapping this RObject was constructed with a TD_CanDowncast argument.

  • T is not the concrete type this RObject<_> was constructed with.

Example
use abi_stable::{
    sabi_trait::doc_examples::Doer_TO, std_types::RBox,
    type_level::downcasting::TD_CanDowncast, RMut, RRef,
};

{
    let mut to: Doer_TO<'_, RBox<()>> =
        Doer_TO::from_value(34usize, TD_CanDowncast);

    // `to.obj` is an RObject
    assert_eq!(to.obj.downcast_as_mut::<usize>().ok(), Some(&mut 34usize));
    assert_eq!(to.obj.downcast_as_mut::<u8>().ok(), None);
}
{
    let mmut = &mut 55usize;
    // `#[sabi_trait]` trait objects constructed from `&mut`
    // use `RMut<'_, ()>` instead of `&'_ mut ()`
    // since `&mut T` can't soundly be transmuted back and forth into `&mut ()`
    let mut to: Doer_TO<'_, RMut<'_, ()>> = Doer_TO::from_ptr(mmut, TD_CanDowncast);

    assert_eq!(to.obj.downcast_as_mut::<usize>().ok(), Some(&mut 55usize));
    assert_eq!(to.obj.downcast_as_mut::<u8>().ok(), None);
}

Unwraps the RObject<_> into a pointer to T, without checking whether T is the type that the RObject was constructed with.

Safety

You must check that T is the type that RObject was constructed with through other means.

Example
use abi_stable::{
    sabi_trait::doc_examples::Doer_TO, std_types::RBox,
    type_level::downcasting::TD_Opaque,
};

let to = || Doer_TO::from_value(5usize, TD_Opaque);

unsafe {
    // `to.obj` is an RObject
    assert_eq!(
        to().obj.unchecked_downcast_into::<usize>(),
        RBox::new(5usize)
    );
}

Unwraps the RObject<_> into a reference to T, without checking whether T is the type that the RObject was constructed with.

Safety

You must check that T is the type that RObject was constructed with through other means.

Example
use abi_stable::{
    sabi_trait::doc_examples::Doer_TO, std_types::RArc,
    type_level::downcasting::TD_Opaque, RMut, RRef,
};

{
    let to: Doer_TO<'_, RArc<()>> = Doer_TO::from_ptr(RArc::new(8usize), TD_Opaque);

    unsafe {
        // `to.obj` is an RObject
        assert_eq!(to.obj.unchecked_downcast_as::<usize>(), &8usize);
    }
}
{
    // `#[sabi_trait]` trait objects constructed from `&`
    // use `RRef<'_, ()>` instead of `&'_ ()`
    // since `&T` can't soundly be transmuted back and forth into `&()`
    let to: Doer_TO<'_, RRef<'_, ()>> = Doer_TO::from_ptr(&13usize, TD_Opaque);

    unsafe {
        assert_eq!(to.obj.unchecked_downcast_as::<usize>(), &13usize);
    }
}
{
    let mmut = &mut 21usize;
    // `#[sabi_trait]` trait objects constructed from `&mut`
    // use `RMut<'_, ()>` instead of `&'_ mut ()`
    // since `&mut T` can't soundly be transmuted back and forth into `&mut ()`
    let to: Doer_TO<'_, RMut<'_, ()>> = Doer_TO::from_ptr(mmut, TD_Opaque);

    unsafe {
        assert_eq!(to.obj.unchecked_downcast_as::<usize>(), &21usize);
    }
}

Unwraps the RObject<_> into a mutable reference to T, without checking whether T is the type that the RObject was constructed with.

Safety

You must check that T is the type that RObject was constructed with through other means.

Example
use abi_stable::{
    sabi_trait::doc_examples::Doer_TO, std_types::RBox,
    type_level::downcasting::TD_Opaque, RMut, RRef,
};

{
    let mut to: Doer_TO<'_, RBox<()>> = Doer_TO::from_value(34usize, TD_Opaque);

    unsafe {
        // `to.obj` is an RObject
        assert_eq!(to.obj.unchecked_downcast_as_mut::<usize>(), &mut 34usize);
    }
}
{
    let mmut = &mut 55usize;
    // `#[sabi_trait]` trait objects constructed from `&mut`
    // use `RMut<'_, ()>` instead of `&'_ mut ()`
    // since `&mut T` can't soundly be transmuted back and forth into `&mut ()`
    let mut to: Doer_TO<'_, RMut<'_, ()>> = Doer_TO::from_ptr(mmut, TD_Opaque);

    unsafe {
        assert_eq!(to.obj.unchecked_downcast_as_mut::<usize>(), &mut 55usize);
    }
}

Creates a shared reborrow of this RObject.

This is only callable if RObject is either Send + Sync or !Send + !Sync.

Example
use abi_stable::{
    sabi_trait::doc_examples::Doer_TO, std_types::RBox,
    type_level::downcasting::TD_Opaque, RMut, RRef,
};

let mut to: Doer_TO<'_, RBox<()>> = Doer_TO::from_value(13usize, TD_Opaque);

// `to.obj` is an RObject
assert_eq!(debug_string(to.obj.reborrow()), "13");
assert_eq!(debug_string(to.obj.reborrow()), "13");

// `#[sabi_trait]` trait objects have an equivalent `sabi_reborrow` method.
assert_eq!(debug_string(to.sabi_reborrow()), "13");
assert_eq!(debug_string(to.sabi_reborrow()), "13");

fn debug_string<T>(to: T) -> String
where
    T: std::fmt::Debug,
{
    format!("{:?}", to)
}

Creates a mutable reborrow of this RObject.

The reborrowed RObject cannot use these methods:

  • RObject::clone

This is only callable if RObject is either Send + Sync or !Send + !Sync.

Example
use abi_stable::{
    sabi_trait::doc_examples::{Doer, Doer_TO},
    std_types::RBox,
    type_level::downcasting::TD_Opaque,
    RMut, RRef,
};

let mut to: Doer_TO<'_, RBox<()>> = Doer_TO::from_value(2usize, TD_Opaque);

// `#[sabi_trait]` trait objects have an equivalent `sabi_reborrow_mut` method,
// which delegate to this method.
assert_eq!(increment(to.sabi_reborrow_mut()).value(), 3);
assert_eq!(increment(to.sabi_reborrow_mut()).value(), 4);

fn increment<T>(mut to: T) -> T
where
    T: Doer,
{
    to.add_into(1);
    to
}

Gets the vtable.

The vtable common to all #[sabi_trait] generated trait objects.

Gets an RRef pointing to the erased object.

Gets an RMut pointing to the erased object.

Gets an RRef pointing to the erased object.

Gets an RMut pointing to the erased object.

Calls the f callback with an MovePtr pointing to the erased object.

Trait Implementations

Clone is implemented for references and smart pointers, using GetPointerKind to decide whether P is a smart pointer or a reference.

RObject does not implement Clone if P == &mut () :

use abi_stable::{
    sabi_trait::{doc_examples::ConstExample_TO, TD_Opaque},
    std_types::*,
};

let mut object = ConstExample_TO::from_value(10usize, TD_Opaque);
let borrow = object.sabi_reborrow_mut();
let _ = borrow.clone();

Here is the same example with sabi_reborrow

use abi_stable::{
    sabi_trait::{doc_examples::ConstExample_TO, TD_Opaque},
    std_types::*,
};

let mut object = ConstExample_TO::from_value(10usize, TD_Opaque);
let borrow = object.sabi_reborrow();
let _ = borrow.clone();

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Formats the value using the given formatter. Read more

Executes the destructor for this type. Read more

The lower-level source of this error, if any. Read more

🔬 This is a nightly-only experimental API. (backtrace)

Returns a stack backtrace, if available, of where this error occurred. Read more

👎 Deprecated since 1.42.0:

use the Display impl or to_string()

👎 Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Whether this type has a single invalid bit-pattern. Read more

The layout of the type provided by implementors.

const-equivalents of the associated types.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

The owned type, stored in RCow::Owned

The borrowed type, stored in RCow::Borrowed

Performs the conversion.

This is always WithMetadata_<Self, Self>

Performs the conversion.

Gets a reference to a field, determined by offset. Read more

Gets a muatble reference to a field, determined by offset. Read more

Gets a const pointer to a field, the field is determined by offset. Read more

Gets a mutable pointer to a field, determined by offset. Read more

Replaces a field (determined by offset) with value, returning the previous value of the field. Read more

Swaps a field (determined by offset) with the same field in right. Read more

Gets a copy of a field (determined by offset). The field is determined by offset. Read more

Replaces a field (determined by offset) with value, returning the previous value of the field. Read more

Swaps a field (determined by offset) with the same field in right. Read more

Gets a copy of a field (determined by offset). The field is determined by offset. Read more

Compares the address of self with the address of other. Read more

Emulates the pipeline operator, allowing method syntax in more places. Read more

The same as piped except that the function takes &Self Useful for functions that take &Self instead of Self. Read more

The same as piped, except that the function takes &mut Self. Useful for functions that take &mut Self instead of Self. Read more

Mutates self using a closure taking self by mutable reference, passing it along the method chain. Read more

Observes the value of self, passing it along unmodified. Useful in long method chains. Read more

Performs a conversion with Into. using the turbofish .into_::<_>() syntax. Read more

Performs a reference to reference conversion with AsRef, using the turbofish .as_ref_::<_>() syntax. Read more

Performs a mutable reference to mutable reference conversion with AsMut, using the turbofish .as_mut_::<_>() syntax. Read more

Drops self using method notation. Alternative to std::mem::drop. Read more

The resulting type after obtaining ownership.

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

🔬 This is a nightly-only experimental API. (toowned_clone_into)

recently added

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

Converts the given value to a String. Read more

Transmutes the element type of this pointer.. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

This is always Self.

Converts a value back to the original type.

Converts a reference back to the original type.

Converts a mutable reference back to the original type.

This is supported on crate feature alloc only.

Converts a box back to the original type.

This is supported on crate feature alloc only.

Converts an Arc back to the original type. Read more

This is supported on crate feature alloc only.

Converts an Rc back to the original type. Read more

Converts a value back to the original type.

Converts a reference back to the original type.

Converts a mutable reference back to the original type.

This is supported on crate feature alloc only.

Converts a box back to the original type.

This is supported on crate feature alloc only.

Converts an Arc back to the original type.

This is supported on crate feature alloc only.

Converts an Rc back to the original type.