@@ -104,6 +104,18 @@ pub mod __private {
104104 pub use syn;
105105}
106106
107+ /// Helper trait providing the path for an attribute.
108+ ///
109+ /// Automatically derived with [`Attribute`], if `#[attribute(ident =
110+ /// "some_ident")]` is provided.
111+ /// ```
112+ pub trait AttributeIdent : Sized {
113+ const ATTRIBUTE_IDENT : & ' static str ;
114+ fn get_attribute_ident ( ) -> & ' static str {
115+ Self :: ATTRIBUTE_IDENT
116+ }
117+ }
118+
107119/// The trait you actually derive on your attribute struct.
108120///
109121/// Basic gist is a struct like this:
@@ -132,7 +144,6 @@ pub mod __private {
132144/// #[collection(authority="Some String", name = r#"Another string"#, views = [Option, ()], some_flag)]
133145/// ```
134146pub trait Attribute : Sized {
135- const IDENT : Option < & ' static str > ;
136147 type Parser : TryExtendOne + Parse + Default ;
137148
138149 #[ doc( hidden) ]
@@ -162,12 +173,15 @@ pub trait Attribute: Sized {
162173 /// - Invalid input is given for a parameter
163174 /// - A non aggregating parameter is specified multiple times
164175 /// - An attribute called [`IDENT`](Self::IDENT) has invalid syntax (e.g. `#attr(a: "a")`)
165- fn from_attributes < ' a > ( attrs : impl IntoIterator < Item = & ' a syn:: Attribute > ) -> Result < Self > {
176+ fn from_attributes < ' a > ( attrs : impl IntoIterator < Item = & ' a syn:: Attribute > ) -> Result < Self >
177+ where
178+ Self : AttributeIdent ,
179+ {
166180 attrs
167181 . into_iter ( )
168182 . filter_map ( |attr| {
169183 attr. path
170- . is_ident ( Self :: IDENT . expect ( r#"To use `from_attributes` you need to pass the attribute name while deriving with `#[attribute(ident="some_ident")]"# ) )
184+ . is_ident ( Self :: ATTRIBUTE_IDENT )
171185 . then ( || attr. parse_args :: < Self :: Parser > ( ) )
172186 } )
173187 . try_fold ( Self :: Parser :: default ( ) , |mut acc, item| {
@@ -201,11 +215,14 @@ pub trait Attribute: Sized {
201215 /// - Invalid input is given for a parameter
202216 /// - A non aggregating parameter is specified multiple times
203217 /// - An attribute called [`IDENT`](Self::IDENT) has invalid syntax (e.g. `#attr(a: "a")`)
204- fn remove_attributes ( attrs : & mut Vec < syn:: Attribute > ) -> Result < Self > {
218+ fn remove_attributes ( attrs : & mut Vec < syn:: Attribute > ) -> Result < Self >
219+ where
220+ Self : AttributeIdent ,
221+ {
205222 let mut parser: Self :: Parser = Default :: default ( ) ;
206223 let mut i = 0 ;
207224 while i < attrs. len ( ) {
208- if attrs[ i] . path . is_ident ( Self :: IDENT . expect ( r#"To use `remove_attributes` you need to pass the attribute name while deriving with `#[attribute(ident="some_ident")]"# ) ) {
225+ if attrs[ i] . path . is_ident ( Self :: ATTRIBUTE_IDENT ) {
209226 parser. try_extend_one ( attrs. remove ( i) . parse_args ( ) ?) ?;
210227 } else {
211228 i += 1 ;
0 commit comments