@@ -13,7 +13,7 @@ pub fn parse(input: TokenStream) -> Vec<ast::Markup> {
1313#[ derive( Clone ) ]
1414struct Parser {
1515 /// If we're inside an attribute, then this contains the attribute name.
16- current_attr : Option < String > ,
16+ current_attr : Option < ast :: AttrName > ,
1717 input : <TokenStream as IntoIterator >:: IntoIter ,
1818}
1919
@@ -580,48 +580,7 @@ impl Parser {
580580 let mut attrs = Vec :: new ( ) ;
581581 loop {
582582 if let Some ( name) = self . try_namespaced_name ( ) {
583- // Attribute
584- match self . peek ( ) {
585- // Non-empty attribute
586- Some ( TokenTree :: Punct ( ref punct) ) if punct. as_char ( ) == '=' => {
587- self . advance ( ) ;
588- // Parse a value under an attribute context
589- assert ! ( self . current_attr. is_none( ) ) ;
590- self . current_attr = Some ( ast:: name_to_string ( name. clone ( ) ) ) ;
591- let attr_type = match self . attr_toggler ( ) {
592- Some ( toggler) => ast:: AttrType :: Optional { toggler } ,
593- None => {
594- let value = self . markup ( ) ;
595- ast:: AttrType :: Normal { value }
596- }
597- } ;
598- self . current_attr = None ;
599- attrs. push ( ast:: Attr :: Named {
600- named_attr : ast:: NamedAttr { name, attr_type } ,
601- } ) ;
602- }
603- // Empty attribute (legacy syntax)
604- Some ( TokenTree :: Punct ( ref punct) ) if punct. as_char ( ) == '?' => {
605- self . advance ( ) ;
606- let toggler = self . attr_toggler ( ) ;
607- attrs. push ( ast:: Attr :: Named {
608- named_attr : ast:: NamedAttr {
609- name : name. clone ( ) ,
610- attr_type : ast:: AttrType :: Empty { toggler } ,
611- } ,
612- } ) ;
613- }
614- // Empty attribute (new syntax)
615- _ => {
616- let toggler = self . attr_toggler ( ) ;
617- attrs. push ( ast:: Attr :: Named {
618- named_attr : ast:: NamedAttr {
619- name : name. clone ( ) ,
620- attr_type : ast:: AttrType :: Empty { toggler } ,
621- } ,
622- } ) ;
623- }
624- }
583+ attrs. push ( self . attr ( ast:: AttrName :: Fixed { value : name } ) ) ;
625584 } else {
626585 match self . peek ( ) {
627586 // Class shorthand
@@ -644,6 +603,18 @@ impl Parser {
644603 name,
645604 } ) ;
646605 }
606+ // Spliced attribute name
607+ Some ( TokenTree :: Group ( ref group) )
608+ if group. delimiter ( ) == Delimiter :: Parenthesis =>
609+ {
610+ match self . markup ( ) {
611+ ast:: Markup :: Splice { expr, .. } => {
612+ attrs. push ( self . attr ( ast:: AttrName :: Splice { expr } ) ) ;
613+ }
614+ // If it's not a splice, backtrack and bail out
615+ _ => break ,
616+ }
617+ }
647618 // If it's not a valid attribute, backtrack and bail out
648619 _ => break ,
649620 }
@@ -665,7 +636,7 @@ impl Parser {
665636 ast:: Attr :: Id { .. } => "id" . to_string ( ) ,
666637 ast:: Attr :: Named { named_attr } => named_attr
667638 . name
668- . clone ( )
639+ . tokens ( )
669640 . into_iter ( )
670641 . map ( |token| token. to_string ( ) )
671642 . collect ( ) ,
@@ -685,6 +656,50 @@ impl Parser {
685656 attrs
686657 }
687658
659+ fn attr ( & mut self , name : ast:: AttrName ) -> ast:: Attr {
660+ match self . peek ( ) {
661+ // Non-empty attribute
662+ Some ( TokenTree :: Punct ( ref punct) ) if punct. as_char ( ) == '=' => {
663+ self . advance ( ) ;
664+ // Parse a value under an attribute context
665+ assert ! ( self . current_attr. is_none( ) ) ;
666+ self . current_attr = Some ( name. clone ( ) ) ;
667+ let attr_type = match self . attr_toggler ( ) {
668+ Some ( toggler) => ast:: AttrType :: Optional { toggler } ,
669+ None => {
670+ let value = self . markup ( ) ;
671+ ast:: AttrType :: Normal { value }
672+ }
673+ } ;
674+ self . current_attr = None ;
675+ ast:: Attr :: Named {
676+ named_attr : ast:: NamedAttr { name, attr_type } ,
677+ }
678+ }
679+ // Empty attribute (legacy syntax)
680+ Some ( TokenTree :: Punct ( ref punct) ) if punct. as_char ( ) == '?' => {
681+ self . advance ( ) ;
682+ let toggler = self . attr_toggler ( ) ;
683+ ast:: Attr :: Named {
684+ named_attr : ast:: NamedAttr {
685+ name : name,
686+ attr_type : ast:: AttrType :: Empty { toggler } ,
687+ } ,
688+ }
689+ }
690+ // Empty attribute (new syntax)
691+ _ => {
692+ let toggler = self . attr_toggler ( ) ;
693+ ast:: Attr :: Named {
694+ named_attr : ast:: NamedAttr {
695+ name : name,
696+ attr_type : ast:: AttrType :: Empty { toggler } ,
697+ } ,
698+ }
699+ }
700+ }
701+ }
702+
688703 /// Parses the name of a class or ID.
689704 fn class_or_id_name ( & mut self ) -> ast:: Markup {
690705 if let Some ( symbol) = self . try_name ( ) {
0 commit comments