@@ -111,26 +111,7 @@ impl<'a> Properties<'a> for FileProps {
111111 )
112112 . map ( |( ( ) , prefs) | FileProp :: Prefs ( prefs) ) ;
113113
114- let tags = helper
115- . parser (
116- keyword ( "tags" ) . to ( ( ) ) ,
117- conditional_term. clone ( ) ,
118- ascii:: ident ( )
119- . map ( |i : & str | i. to_owned ( ) )
120- . separated_by ( just ( ',' ) . padded_by ( inline_whitespace ( ) ) )
121- . collect ( )
122- . delimited_by (
123- just ( '[' ) . padded_by ( inline_whitespace ( ) ) ,
124- just ( ']' ) . padded_by ( inline_whitespace ( ) ) ,
125- )
126- . validate ( |idents : Vec < _ > , e, emitter| {
127- if idents. is_empty ( ) {
128- emitter. emit ( Rich :: custom ( e. span ( ) , "no tags specified" ) ) ;
129- }
130- idents
131- } ) ,
132- )
133- . map ( |( ( ) , tags) | FileProp :: Tags ( tags) ) ;
114+ let tags = tags_parser ( helper, conditional_term. clone ( ) ) . map ( FileProp :: Tags ) ;
134115
135116 let disabled = helper
136117 . parser (
@@ -196,6 +177,55 @@ impl<'a> Properties<'a> for FileProps {
196177 }
197178}
198179
180+ fn tags_parser < ' a , T > (
181+ helper : & mut PropertiesParseHelper < ' a > ,
182+ conditional_term : impl Parser < ' a , & ' a str , T , ParseError < ' a > > ,
183+ ) -> impl Parser < ' a , & ' a str , PropertyValue < T , Vec < String > > , ParseError < ' a > > {
184+ use crate :: chumsky:: { error:: Error , util:: MaybeRef } ;
185+
186+ let tag_ident = {
187+ let underscore_or_hyphen = |c| matches ! ( c, '_' | '-' ) ;
188+ any ( )
189+ . try_map ( move |c : char , span| {
190+ if c. is_ascii_alphabetic ( ) || underscore_or_hyphen ( c) {
191+ Ok ( c)
192+ } else {
193+ Err ( Error :: < & ' a str > :: expected_found (
194+ [ ] ,
195+ Some ( MaybeRef :: Val ( c) ) ,
196+ span,
197+ ) )
198+ }
199+ } )
200+ . then (
201+ any ( )
202+ . filter ( move |c : & char | c. is_ascii_alphanumeric ( ) || underscore_or_hyphen ( * c) )
203+ . repeated ( ) ,
204+ )
205+ . to_slice ( )
206+ } ;
207+ helper
208+ . parser (
209+ keyword ( "tags" ) . to ( ( ) ) ,
210+ conditional_term,
211+ tag_ident
212+ . map ( |i : & str | i. to_owned ( ) )
213+ . separated_by ( just ( ',' ) . padded_by ( inline_whitespace ( ) ) )
214+ . collect ( )
215+ . delimited_by (
216+ just ( '[' ) . padded_by ( inline_whitespace ( ) ) ,
217+ just ( ']' ) . padded_by ( inline_whitespace ( ) ) ,
218+ )
219+ . validate ( |idents : Vec < _ > , e, emitter| {
220+ if idents. is_empty ( ) {
221+ emitter. emit ( Rich :: custom ( e. span ( ) , "no tags specified" ) ) ;
222+ }
223+ idents
224+ } ) ,
225+ )
226+ . map ( |( ( ) , tags) | tags)
227+ }
228+
199229#[ test]
200230fn file_props ( ) {
201231 let parser = FileProps :: property_parser ( & mut PropertiesParseHelper :: new ( 0 ) ) ;
0 commit comments