1+ use std:: collections:: HashMap ;
2+
13use crate :: STATE ;
24use anyhow:: { anyhow, bail, Result } ;
35use darling:: { FromMeta , ToTokens } ;
46use proc_macro2:: { Ident , Span , TokenStream } ;
57use quote:: quote;
6- use syn:: { Attribute , AttributeArgs , Expr , ItemStruct } ;
8+ use syn:: { Attribute , AttributeArgs , Expr , ItemStruct , Token } ;
79
810#[ derive( Debug , Default ) ]
911pub struct Class {
@@ -12,12 +14,14 @@ pub struct Class {
1214 pub interfaces : Vec < String > ,
1315 pub methods : Vec < crate :: method:: Method > ,
1416 pub constants : Vec < crate :: constant:: Constant > ,
17+ pub properties : HashMap < String , ( String , Option < String > ) > ,
1518}
1619
1720#[ derive( Debug ) ]
1821pub enum ParsedAttribute {
1922 Extends ( Expr ) ,
2023 Implements ( Expr ) ,
24+ Property ( Box < PropertyAttr > ) ,
2125}
2226
2327#[ derive( Default , Debug , FromMeta ) ]
@@ -32,6 +36,7 @@ pub fn parser(args: AttributeArgs, mut input: ItemStruct) -> Result<TokenStream>
3236
3337 let mut parent = None ;
3438 let mut interfaces = vec ! [ ] ;
39+ let mut properties = HashMap :: < String , ( String , Option < String > ) > :: new ( ) ;
3540
3641 input. attrs = {
3742 let mut unused = vec ! [ ] ;
@@ -44,6 +49,15 @@ pub fn parser(args: AttributeArgs, mut input: ItemStruct) -> Result<TokenStream>
4449 ParsedAttribute :: Implements ( class) => {
4550 interfaces. push ( class. to_token_stream ( ) . to_string ( ) ) ;
4651 }
52+ ParsedAttribute :: Property ( attr) => {
53+ properties. insert (
54+ attr. name . to_string ( ) ,
55+ (
56+ attr. default . to_token_stream ( ) . to_string ( ) ,
57+ attr. flags . map ( |flags| flags. to_token_stream ( ) . to_string ( ) ) ,
58+ ) ,
59+ ) ;
60+ }
4761 } ,
4862 None => unused. push ( attr) ,
4963 }
@@ -93,6 +107,7 @@ pub fn parser(args: AttributeArgs, mut input: ItemStruct) -> Result<TokenStream>
93107 class_name,
94108 parent,
95109 interfaces,
110+ properties,
96111 ..Default :: default ( )
97112 } ;
98113
@@ -111,6 +126,31 @@ pub fn parser(args: AttributeArgs, mut input: ItemStruct) -> Result<TokenStream>
111126 Ok ( output)
112127}
113128
129+ #[ derive( Debug ) ]
130+ pub struct PropertyAttr {
131+ pub name : Ident ,
132+ pub default : Expr ,
133+ pub flags : Option < Expr > ,
134+ }
135+
136+ impl syn:: parse:: Parse for PropertyAttr {
137+ fn parse ( input : syn:: parse:: ParseStream ) -> syn:: Result < Self > {
138+ let name: Ident = input. parse ( ) ?;
139+ let _: Token ! [ =] = input. parse ( ) ?;
140+ let default: Expr = input. parse ( ) ?;
141+ let flags = input
142+ . parse :: < Token ! [ , ] > ( )
143+ . and_then ( |_| input. parse :: < Expr > ( ) )
144+ . ok ( ) ;
145+
146+ Ok ( PropertyAttr {
147+ name,
148+ default,
149+ flags,
150+ } )
151+ }
152+ }
153+
114154fn parse_attribute ( attr : & Attribute ) -> Result < Option < ParsedAttribute > > {
115155 let name = attr. path . to_token_stream ( ) . to_string ( ) ;
116156
@@ -127,6 +167,13 @@ fn parse_attribute(attr: &Attribute) -> Result<Option<ParsedAttribute>> {
127167 . map_err ( |_| anyhow ! ( "Unable to parse `#[{}]` attribute." , name) ) ?;
128168 Some ( ParsedAttribute :: Implements ( meta) )
129169 }
170+ "property" => {
171+ let attr: PropertyAttr = attr
172+ . parse_args ( )
173+ . map_err ( |_| anyhow ! ( "Unable to parse `#[{}]` attribute." , name) ) ?;
174+
175+ Some ( ParsedAttribute :: Property ( Box :: new ( attr) ) )
176+ }
130177 _ => None ,
131178 } )
132179}
0 commit comments