44// SPDX-License-Identifier: MIT OR Apache-2.0 
55
66use  crate :: { parser,  syntax:: path:: path_compare_str} ; 
7+ use  std:: collections:: btree_map:: Entry ; 
78use  std:: collections:: BTreeMap ; 
89use  syn:: { spanned:: Spanned ,  Attribute ,  Error ,  Result } ; 
910
10- pub  struct  ParsedAttribute < ' a >  { 
11-     pub  cxx_qt_attrs :  BTreeMap < & ' a  str ,  & ' a  Attribute > , 
12-     pub  passthrough_attrs :  BTreeMap < & ' a  str ,  & ' a  Attribute > , 
11+ #[ derive( Clone ) ]  
12+ pub  struct  ParsedAttributes  { 
13+     pub  cxx_qt_attrs :  BTreeMap < String ,  Vec < Attribute > > , 
14+     pub  passthrough_attrs :  Vec < Attribute > , 
1315} 
1416
1517/// Iterate the attributes of the method to extract cfg attributes 
@@ -30,20 +32,28 @@ pub fn extract_docs(attrs: &[Attribute]) -> Vec<Attribute> {
3032        . collect ( ) 
3133} 
3234
33- impl < ' a >  ParsedAttribute < ' a >  { 
35+ impl < ' a >  ParsedAttributes  { 
3436    /// Collects a Map of all attributes found from the allowed list 
3537/// Will error if an attribute which is not in the allowed list is found 
3638pub  fn  require_attributes ( 
37-         attrs :  & ' a   [ Attribute ] , 
39+         mut   attrs :  Vec < Attribute > , 
3840        allowed :  & ' a  [ & str ] , 
39-     )  -> Result < ParsedAttribute < ' a > >  { 
40-         let  mut  output = BTreeMap :: default ( ) ; 
41-         for  attr in  attrs { 
41+     )  -> Result < ParsedAttributes >  { 
42+         let  mut  output = BTreeMap :: < String ,   Vec < Attribute > > :: default ( ) ; 
43+         for  attr in  attrs. drain ( .. )  { 
4244            let  index = allowed
4345                . iter ( ) 
4446                . position ( |string| path_compare_str ( attr. meta . path ( ) ,  & parser:: split_path ( string) ) ) ; 
4547            if  let  Some ( index)  = index { 
46-                 output. insert ( allowed[ index] ,  attr) ;  // TODO: Doesn't error on duplicates 
48+                 // TODO: ATTR Doesn't error on duplicates / distinguish allowed and disallowed duplicates 
49+                 match  output. entry ( allowed[ index] . into ( ) )  { 
50+                     Entry :: Occupied ( mut  entry)  => { 
51+                         entry. get_mut ( ) . push ( attr) ; 
52+                     } 
53+                     Entry :: Vacant ( entry)  => { 
54+                         entry. insert ( vec ! [ attr] ) ; 
55+                     } 
56+                 } 
4757            }  else  { 
4858                return  Err ( Error :: new ( 
4959                    attr. span ( ) , 
@@ -56,23 +66,54 @@ impl<'a> ParsedAttribute<'a> {
5666        } 
5767        Ok ( Self  { 
5868            cxx_qt_attrs :  output, 
59-             passthrough_attrs :  Default :: default ( ) , 
69+             passthrough_attrs :  Default :: default ( ) ,   // TODO: ATTR Pass the actual docs, cfgs, etc... here 
6070        } ) 
6171    } 
6272
73+     // TODO: ATTR Can this return references instead? 
74+     pub  fn  extract_docs ( & self )  -> Vec < Attribute >  { 
75+         self . cxx_qt_attrs 
76+             . values ( ) 
77+             . flatten ( ) 
78+             . filter ( |attr| path_compare_str ( attr. meta . path ( ) ,  & [ "doc" ] ) ) 
79+             . map ( |attr| ( * attr) . clone ( ) ) 
80+             . collect ( ) 
81+     } 
82+ 
83+     // TODO: ATTR Can this return references instead 
84+     pub  fn  extract_cfgs ( & self )  -> Vec < Attribute >  { 
85+         self . cxx_qt_attrs 
86+             . values ( ) 
87+             . flatten ( ) 
88+             . filter ( |attr| path_compare_str ( attr. meta . path ( ) ,  & [ "cfg" ] ) ) 
89+             . map ( |attr| ( * attr) . clone ( ) ) 
90+             . collect ( ) 
91+     } 
92+ 
93+     /// Returns all the attributes stored within the struct 
94+ pub  fn  all_attrs ( & self )  -> Vec < & Attribute >  { 
95+         self . cxx_qt_attrs . values ( ) . flatten ( ) . collect ( ) 
96+     } 
97+ 
98+     /// Returns all the attributes stored within the struct (CLONE) WIP 
99+ pub  fn  clone_attrs ( & self )  -> Vec < Attribute >  { 
100+         self . cxx_qt_attrs 
101+             . values ( ) 
102+             . flatten ( ) 
103+             . cloned ( ) 
104+             . collect :: < Vec < _ > > ( ) 
105+     } 
106+ 
63107    // Wrapper methods for the internal BTreeMaps 
64108    // TODO: Refactor usage to use more specialised methods / rename 
65109
66110    /// Search in first the CXX-Qt, and then passthrough attributes by key 
67- pub  fn  get ( & self ,  key :  & str )  -> Option < & Attribute >  { 
68-         self . cxx_qt_attrs 
69-             . get ( key) 
70-             . or ( self . passthrough_attrs . get ( key) ) 
71-             . map ( |attr| & * * attr) 
111+ pub  fn  get ( & self ,  key :  & str )  -> Option < & Vec < Attribute > >  { 
112+         self . cxx_qt_attrs . get ( key)  // TODO: Check passthrough here too 
72113    } 
73114
74115    /// Check if CXX-Qt or passthrough attributes contains a particular key 
75116pub  fn  contains_key ( & self ,  key :  & str )  -> bool  { 
76-         self . cxx_qt_attrs . contains_key ( key)  ||  self . passthrough_attrs . contains_key ( key ) 
117+         self . cxx_qt_attrs . contains_key ( key)  // TODO: Check in passthrough too 
77118    } 
78119} 
0 commit comments