Module abi_stable::docs::sabi_trait_inherent

source ·
Expand description

Shared docs for inherent items of sabi_trait trait objects.

<trait> here is a generic way to refer to the name of “a trait that’s annotated with the sabi_trait attribute macro”.

The trait used in method examples :

#[abi_stable::sabi_trait]
pub trait Action: Debug {
    /// Gets the current value of `self`.
    fn get(&self) -> usize;

    /// Adds `val` into `self`, returning the new value.
    fn add_mut(&mut self, val: usize) -> usize;

    /// Adds `val` into `self`, returning the new value.
    #[sabi(last_prefix_field)]
    fn add_into(self, val: usize) -> usize;
}

§Methods

These are the common methods for the <trait>_TO ffi-safe trait object type generated by the sabi_trait attribute.

-from_ptr

-from_value

-from_const

-from_sabi

-sabi_reborrow_mut

-sabi_reborrow

§from_ptr method

impl<'lt, ErasedPtr, …> Trait_TO<'lt, ErasedPtr, …> {
    pub fn from_ptr<Ptr, Downcasting>(
        pointer: Ptr,
        can_it_downcast: Downcasting
    ) -> Self

Constructs <trait>_TO from a pointer to a type that implements <trait>

The can_it_downcast parameter describes whether the trait object can be converted back into the original type or not.
Its possible values are TD_CanDowncast and TD_Opaque.

Method docs for Action_TO::from_ptr

Example:

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

// From an RBox
{
    // The type annotation is purely for the reader.
    let mut object: Action_TO<'static, RBox<()>> =
        Action_TO::from_ptr(RBox::new(10_usize), TD_CanDowncast);

    assert_eq!(object.get(), 10);

    assert_eq!(object.add_mut(3), 13);
    assert_eq!(object.get(), 13);

    // consumes `object`, now it can't be used anymore.
    assert_eq!(object.add_into(7), 20);
}

// From a reference
{
    // `Action_TO`s constructed from `&` are `Action_TO<'_, RRef<'_, ()>>`
    // since `&T` can't soundly be transmuted back and forth into `&()`
    let object: Action_TO<'static, RRef<'static, ()>> =
        Action_TO::from_ptr(&20_usize, TD_CanDowncast);

    assert_eq!(object.get(), 20);
}

// From a mutable reference
{
    let mut val = 30_usize;

    // `Action_TO`s constructed from `&mut` are `Action_TO<'_, RMut<'_, ()>>`
    // since `&mut T` can't soundly be transmuted back and forth into `&mut ()`
    let mut object: Action_TO<'static, RMut<'_, ()>> =
        Action_TO::from_ptr(&mut val, TD_CanDowncast);

    assert_eq!(object.get(), 30);

    assert_eq!(object.add_mut(3), 33);
    assert_eq!(object.get(), 33);

    drop(object);

    assert_eq!(val, 33);
}

// From an RArc
{
    let object: Action_TO<'static, RArc<()>> =
        Action_TO::from_ptr(RArc::new(40), TD_CanDowncast);

    assert_eq!(object.get(), 40);
}

§from_value method

impl<'lt, …> Trait_TO<'lt, RBox<()>, …> {
    pub fn from_value<_OrigPtr, Downcasting>(
        pointer: _OrigPtr,
        can_it_downcast: Downcasting
    ) -> Self

Constructs <trait>_TO from a type that implements <trait>, wrapping that value in an RBox.

The can_it_downcast parameter describes whether the trait object can be converted back into the original type or not.
Its possible values are TD_CanDowncast and TD_Opaque.

Method docs for Action_TO::from_value

Example:

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

// The type annotation is purely for the reader.
let mut object: Action_TO<'static, RBox<()>> =
    Action_TO::from_value(100_usize, TD_CanDowncast);

assert_eq!(object.get(), 100);

assert_eq!(object.add_mut(3), 103);
assert_eq!(object.get(), 103);

// consumes `object`, now it can't be used anymore.
assert_eq!(object.add_into(7), 110);

§from_const method

impl<'lt, 'sub, …> Trait_TO<'lt, RRef<'sub, ()>, …> {
    pub const fn from_const<T, Downcasting>(
        pointer: &'sub T,
        can_it_downcast: Downcasting,
    ) -> Self

Const-constructs <trait>_TO from a constant that implements <trait>,

The can_it_downcast parameter describes whether the trait object can be converted back into the original type or not.
Its possible values are TD_CanDowncast and TD_Opaque.

Method docs for Action_TO::from_const

Example:

use abi_stable::{
    sabi_trait::doc_examples::Action_trait::{Action_CTO, Action_TO},
    std_types::RBox,
    type_level::downcasting::TD_CanDowncast,
};

const TO: Action_CTO<'_, '_> = Action_TO::from_const(&200, TD_CanDowncast);

assert_eq!(TO.get(), 200);

§from_sabi method

impl<'lt, ErasedPtr, …> Trait_TO<'lt, ErasedPtr, …> {
    pub fn from_sabi(obj: Trait_Backend<'lt, ErasedPtr, …>) -> Self

Constructs <trait>_TO from the backend trait object type, either RObject or DynTrait.

Method docs for Action_TO::from_sabi

This allows calling methods on the .obj field of <trait>_TO that consume the backend and return it back.

For Action_TO specifically, RObject is the backend.

Example:

use abi_stable::{
    pointer_trait::{CanTransmuteElement, OwnedPointer},
    sabi_trait::{
        doc_examples::Action_trait::{Action_Interface, Action_TO},
        RObject,
    },
    std_types::RBox,
    type_level::downcasting::TD_CanDowncast,
};

let mut object: Action_TO<'static, RBox<()>> =
    Action_TO::from_value(700, TD_CanDowncast);

object = try_downcast::<_, u32>(object).unwrap_err();

object = try_downcast::<_, String>(object).unwrap_err();

assert_eq!(*try_downcast::<_, usize>(object).unwrap(), 700);

fn try_downcast<P, T>(
    object: Action_TO<'static, P>,
) -> Result<P::TransmutedPtr, Action_TO<'static, P>>
where
    T: 'static,
    // This bound is required to call `downcast_into` on the `obj: RObject<…>` field
    P: OwnedPointer<PtrTarget = ()> + CanTransmuteElement<T>,
{
    object
        .obj
        .downcast_into()
        .map_err(|e| Action_TO::from_sabi(e.into_inner()))
}

§sabi_reborrow method

impl<'lt, ErasedPtr, …> Trait_TO<'lt, ErasedPtr, …> {
    pub fn sabi_reborrow<'r>(&'r self) -> Trait_TO<'lt, RRef<'r, ()>, …> {

Reborrows a &'r <trait>_TO<'lt, …> into a <trait>_TO<'lt, RRef<'r, ()>, …>.

Method docs for Action_TO::sabi_reborrow

This allows passing the trait object to functions that take a <trait>_TO<'b, RRef<'a, ()>, …>, and functions generic over the traits that <trait>_TO implements.

This method is only available for traits that either:

  • require neither Send nor Sync,
  • require Send + Sync.

Example:

use abi_stable::{
    sabi_trait::doc_examples::Action_TO, std_types::RBox,
    type_level::downcasting::TD_CanDowncast, RRef,
};

let mut object: Action_TO<'static, RBox<()>> =
    Action_TO::from_value(300_usize, TD_CanDowncast);

assert_eq!(to_debug_string(object.sabi_reborrow()), "300");

assert_eq!(object.add_mut(7), 307);
assert_eq!(get_usize(object.sabi_reborrow()), 307);

assert_eq!(object.add_mut(14), 321);
// last use of `object`, so we can move it into the function
assert_eq!(to_debug_string(object), "321");

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

fn get_usize(x: Action_TO<'_, RRef<'_, ()>>) -> usize {
    x.get()
}

§sabi_reborrow_mut method

impl<'lt, ErasedPtr, …> Trait_TO<'lt, ErasedPtr, …> {
    pub fn sabi_reborrow_mut<'r>(&'r mut self) -> Trait_TO<'lt, RMut<'r, ()>, …> {

Reborrows a &'r mut <trait>_TO<'b, …> into a <trait>_TO<'b, RMut<'r, ()>, …>.

Method docs for Action_TO::sabi_reborrow_mut

This allows passing the trait object to functions that take a <trait>_TO<'b, RMut<'a, ()>, …>, and functions generic over the traits that <trait>_TO implements.

This method is only available for traits that either:

  • require neither Send nor Sync,
  • require Send + Sync.

Example:

use abi_stable::{
    pointer_trait::AsMutPtr, sabi_trait::doc_examples::Action_TO, std_types::RBox,
    type_level::downcasting::TD_CanDowncast,
};

let mut object: Action_TO<'static, RBox<()>> =
    Action_TO::from_value(400_usize, TD_CanDowncast);

assert_eq!(add_mut(object.sabi_reborrow_mut(), 6), 406);

assert_eq!(add_mut(object.sabi_reborrow_mut(), 10), 416);

// last use of `object`, so we can move it into the function
assert_eq!(add_mut(object, 20), 436);

fn add_mut<P>(mut x: Action_TO<'_, P>, how_much: usize) -> usize
where
    // Needed for calling mutable methods on `Action_TO`
    P: AsMutPtr<PtrTarget = ()>,
{
    x.add_mut(how_much)
}