extern crate alloc;
use TokenStream;
use quote;
use ToTokens;
use Parse;
/// 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 mirror_mirror as some_library;
/// 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`.
///
/// [`Reflect`]: crate::Reflect
/// Private API: Do not use!
;