Skip to main content

reflect_remote

Attribute Macro reflect_remote 

Source
#[reflect_remote]
Expand description

Generates a wrapper type that can be used to “derive Reflect” for remote types.

This works by wrapping the remote type in a generated wrapper that has the #[repr(transparent)] attribute. The generated ReflectRemote implementation uses this representation to convert between the wrapper and remote type.

§Defining the Wrapper

Before defining the wrapper type, please note that it is required that all fields of the remote type are public. The generated code will, at times, need to access or mutate them, and we do not currently have a way to assign getters/setters to each field (but this may change in the future).

The wrapper definition should match the remote type 1-to-1. This includes the naming and ordering of the fields and variants.

Generics and lifetimes do not need to have the same names, however, they do need to follow the same order. Additionally, whether generics are inlined or placed in a where clause should not matter.

Lastly, all macros and doc-comments should be placed below this attribute. If they are placed above, they will not be properly passed to the generated wrapper type.

§Example

Given a remote type, RemoteType:

#[derive(Default)]
struct RemoteType<T>
where
  T: Default + Clone,
{
  pub foo: T,
  pub bar: usize
}

We would define our wrapper type as such:

ⓘ
use external_crate::RemoteType;

#[reflect_remote(RemoteType<T>)]
#[derive(Default)]
pub struct WrapperType<T: Default + Clone> {
  pub foo: T,
  pub bar: usize
}

Apart from all the reflection trait implementations, this generates something like the following:

ⓘ
use external_crate::RemoteType;

#[derive(Default)]
#[repr(transparent)]
pub struct Wrapper<T: Default + Clone>(RemoteType<T>);

§Usage as a Field

You can tell Reflect to use a remote type’s wrapper internally on fields of a struct or enum. This allows the real type to be used as usual while Reflect handles everything internally. To do this, add the #[reflect(remote = path::to::MyType)] attribute to your field:

ⓘ
#[derive(Reflect)]
struct SomeStruct {
  #[reflect(remote = RemoteTypeWrapper)]
  data: RemoteType
}

§Conversion

The wrapper type must implement ReflectRemote with Remote equal to the field’s actual type. Generated reflection code uses the wrapper’s conversion methods; in particular, FromReflect calls ReflectRemote::into_remote to construct the field value.