[][src]Enum remote_trait_object::ServiceRef

pub enum ServiceRef<T: ?Sized + Service> {
    Export(ServiceToExport<T>),
    Import(ServiceToImport<T>),
}

A union of ServiceToExport and ServiceToImport

In most case, you will mostly use only this struct to export and import services.

This is needed when you want to export and import a service via another service, but using a common single trait as a channel.

Suppose you want to export Box<dyn Pizza> by returning it in another service's method, fn order_pizza(). One way of doing this is defining two traits, one for export and one for import. Crate that wants to implement & export a PizzaStore and export Pizza will have following code

use remote_trait_object::*;

#[service]
pub trait Pizza: Service {}

#[service(no_proxy)]
pub trait PizzaStore: Service {
    fn order_pizza(&self) -> ServiceToExport<dyn Pizza>;
}

On the other hand, crate that wants to import & remotely call a PizzaStore and import Pizza will have following code

use remote_trait_object::*;

#[service]
pub trait Pizza: Service {}

#[service(no_skeleton)]
pub trait PizzaStore: Service {
    fn order_pizza(&self) -> ServiceToImport<dyn Pizza>;
}

This works perfectly fine, by returning ServiceToExport::new(..) in the former and calling ServiceToImport::into_remote(the_return_value) in the latter, because the two PizzaStores are compatible since ServiceToImport and ServiceToExport are compatible.

However, suppose the case where the two parties may have a common dependent crate which would have defined such a common service trait, or even the case where the two parties are in the same crate. It becomes somewhat bothersome to have both duplicated traits only because of ServiceToExport and ServiceToImport.

ServiceRef is for such purpose. Instead of denoting both ServiceToExport and ServiceToImport for two separate traits, just use a single common trait with those two types replaced with ServiceRef in the very same place.

The above two traits now become a single trait.

use remote_trait_object::*;

#[service]
pub trait Pizza: Service {}

#[service]
pub trait PizzaStore: Service {
    fn order_pizza(&self) -> ServiceRef<dyn Pizza>;
}

And this PizzaStore can be both

  • implemented and exported - you will be using Import variant for an argument, and Export variant for the return value.
  • imported and locally invoked - you will be using Export variant for an argument, and Import variant for the return value.

Example

// EXPORTER SIDE
impl PizzaStore for SomeType {
    fn order_pizza(&self) -> ServiceRef<dyn Pizza> {
        ServiceRef::create_export(Box::new(SomePizza) as Box<dyn Pizza>)
    }
}

// IMPORTER SIDE
let store: Box<dyn PizzaStore> = some_store();
let pizza: Box<dyn Pizza> = store.order_pizza().unwrap_import().into_proxy();

Variants

Export(ServiceToExport<T>)
Import(ServiceToImport<T>)

Implementations

impl<T: ?Sized + Service> ServiceRef<T>[src]

pub fn create_export(service: impl IntoSkeleton<T>) -> Self[src]

Creates an Export variant from a smart pointer of a service object.

It simply ServiceRef::Export(ServiceToExport::new(service)).

pub fn unwrap_import(self) -> ServiceToImport<T>[src]

Unwraps as an Import variant.

It panics if it is Export.

pub fn into_object<P: ImportProxy<T> + FromSkeleton<T>>(self) -> P[src]

Converts into the object with whatever smart pointer type you want, for both variants.

If ServiceRef is constructed with Import (the common case), it is same as unwrap_import().into_proxy(). If ServiceRef is constructed with Export (where the ServiceRef is given by local object), it just create a light-weight object that simply wraps the skeleton, not involving any connections.

Trait Implementations

impl<'de, T: ?Sized + Service> Deserialize<'de> for ServiceRef<T>[src]

impl<T: ?Sized + Service> Serialize for ServiceRef<T>[src]

Auto Trait Implementations

impl<T> !RefUnwindSafe for ServiceRef<T>[src]

impl<T: ?Sized> Send for ServiceRef<T>[src]

impl<T> !Sync for ServiceRef<T>[src]

impl<T: ?Sized> Unpin for ServiceRef<T> where
    T: Unpin
[src]

impl<T> !UnwindSafe for ServiceRef<T>[src]

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> DeserializeOwned for T where
    T: for<'de> Deserialize<'de>, 
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.