bevy_reflect_derive/
reflect_opaque.rs

1use crate::{
2    container_attributes::ContainerAttributes, derive_data::ReflectTraitToImpl,
3    type_path::CustomPathDef,
4};
5use syn::{parenthesized, parse::ParseStream, token::Paren, Attribute, Generics, Path};
6
7/// A struct used to define a simple reflection-opaque types (including primitives).
8///
9/// This takes the form:
10///
11/// ```ignore (Method expecting TokenStream is better represented with raw tokens)
12/// // Standard
13/// ::my_crate::foo::Bar(TraitA, TraitB)
14///
15/// // With generics
16/// ::my_crate::foo::Bar<T1: Bar, T2>(TraitA, TraitB)
17///
18/// // With generics and where clause
19/// ::my_crate::foo::Bar<T1, T2> where T1: Bar (TraitA, TraitB)
20///
21/// // With a custom path (not with impl_from_reflect_opaque)
22/// (in my_crate::bar) Bar(TraitA, TraitB)
23/// ```
24pub(crate) struct ReflectOpaqueDef {
25    #[cfg_attr(
26        not(feature = "documentation"),
27        expect(
28            dead_code,
29            reason = "The is used when the `documentation` feature is enabled.",
30        )
31    )]
32    pub attrs: Vec<Attribute>,
33    pub type_path: Path,
34    pub generics: Generics,
35    pub traits: Option<ContainerAttributes>,
36    pub custom_path: Option<CustomPathDef>,
37}
38
39impl ReflectOpaqueDef {
40    pub fn parse_reflect(input: ParseStream) -> syn::Result<Self> {
41        Self::parse(input, ReflectTraitToImpl::Reflect)
42    }
43
44    pub fn parse_from_reflect(input: ParseStream) -> syn::Result<Self> {
45        Self::parse(input, ReflectTraitToImpl::FromReflect)
46    }
47
48    fn parse(input: ParseStream, trait_: ReflectTraitToImpl) -> syn::Result<Self> {
49        let attrs = input.call(Attribute::parse_outer)?;
50
51        let custom_path = CustomPathDef::parse_parenthesized(input)?;
52
53        let type_path = Path::parse_mod_style(input)?;
54        let mut generics = input.parse::<Generics>()?;
55        generics.where_clause = input.parse()?;
56
57        let mut traits = None;
58        if input.peek(Paren) {
59            let content;
60            parenthesized!(content in input);
61            traits = Some({
62                let mut attrs = ContainerAttributes::default();
63                attrs.parse_terminated(&content, trait_)?;
64                attrs
65            });
66        }
67        Ok(Self {
68            attrs,
69            type_path,
70            generics,
71            traits,
72            custom_path,
73        })
74    }
75}