#[derive(Reflect)]
{
// Attributes available to this derive:
#[reflect]
}
Expand description
Derive an implementation of Reflect and other appropriate traits.
§Structs
On structs #[derive(Reflect)] will also derive Struct and FromReflect.
use mirror_mirror::Reflect;
#[derive(Reflect, Clone, Debug)]
struct Foo {
a: i32,
b: bool,
c: String,
}Unit structs are treated as tuple structs with no fields.
§Tuple structs
On tuple structs #[derive(Reflect)] will also derive TupleStruct and FromReflect.
use mirror_mirror::Reflect;
#[derive(Reflect, Clone, Debug)]
struct Foo(i32, bool, String);§Enums
On enums #[derive(Reflect)] will also derive Enum and FromReflect.
use mirror_mirror::Reflect;
#[derive(Reflect, Clone, Debug)]
enum Foo {
A(i32),
B { b: bool },
C,
}§Options
§opt_out
By default types are required to implement Clone and Debug. You can opt-out of these
requirements with #[reflect(opt_out(Clone, Debug))]
use mirror_mirror::Reflect;
#[derive(Reflect)]
#[reflect(opt_out(Debug, Clone))]
struct Foo(i32);This changes the implementation of Reflect::clone_reflect and Reflect::debug to something
that works for any type but is less performant.
You can also opt-out of deriving FromReflect so you can provide you own implementation:
use mirror_mirror::{Reflect, FromReflect};
#[derive(Reflect, Debug, Clone)]
#[reflect(opt_out(FromReflect))]
struct Foo(i32);
impl FromReflect for Foo {
fn from_reflect(value: &dyn Reflect) -> Option<Self> {
Some(Self(*value.downcast_ref::<i32>()?))
}
}§skip
You can exclude fields or variants from being reflected with #[reflect(skip)]. The type of the skipped field/variant is
required to implement Default by the default FromReflect implementation.
use mirror_mirror::{Reflect, FromReflect};
#[derive(Reflect, Debug, Clone)]
struct Foo {
#[reflect(skip)]
not_reflect: NotReflect,
}
#[derive(Reflect, Debug, Clone)]
struct Bar(#[reflect(skip)] NotReflect);
#[derive(Reflect, Debug, Clone)]
enum Baz {
#[reflect(skip)]
OnVariant(NotReflect),
OnTupleField(#[reflect(skip)] NotReflect),
OnStructField {
#[reflect(skip)]
not_reflect: NotReflect,
}
}
// A type that isn't compatible with reflection
#[derive(Debug, Clone, Default)]
struct NotReflect;§from_reflect_with
You can override FromReflect for a single field by specifying a function to do the
conversion:
use mirror_mirror::{Reflect, FromReflect};
#[derive(Reflect, Debug, Clone)]
struct Foo {
#[reflect(from_reflect_with(n_from_reflect))]
n: i32,
}
fn n_from_reflect(field: &dyn Reflect) -> Option<i32> {
Some(*field.downcast_ref::<i32>()?)
}§meta
Metadata associated with types or enum variants can be added with #[reflect(meta(...))]
use mirror_mirror::{
Reflect,
key_path,
key_path::GetTypePath,
FromReflect,
type_info::{GetMeta, DescribeType},
};
#[derive(Reflect, Debug, Clone)]
#[reflect(meta(
// a comma separated list of `key = value` pairs.
//
// `key` must be an identifier and `value` can be anything that
// implements `Reflect`
item_key = "item value",
))]
struct Foo {
#[reflect(meta(field_key = 1337))]
n: i32,
}
// Access the metadata through the type information
let type_info = <Foo as DescribeType>::type_descriptor();
assert_eq!(
type_info.get_meta::<String>("item_key").unwrap(),
"item value",
);
assert_eq!(
type_info
.as_struct()
.unwrap()
.field_type("n")
.unwrap()
.get_meta::<i32>("field_key")
.unwrap(),
1337,
);§crate_name
You can specify a “use path” for mirror_mirror with crate_name. This is useful if you’re
using a library that re-exports mirror_mirror’s derive macro:
use some_library::Reflect;
#[derive(Reflect, Debug, Clone)]
#[reflect(crate_name(some_library))]
struct Foo {
n: i32,
}This causes the macro generate paths like some_library::FromReflect.