11use std:: fmt:: Write ;
2+ use std:: iter;
23use std:: iter:: Peekable ;
34use std:: path:: Path ;
45
@@ -31,10 +32,10 @@ enum Def<'a> {
3132 Module ( Module < ' a > ) ,
3233}
3334
34- /// A symbol, either a leaf or with modifiers.
35+ /// A symbol, either a leaf or with modifiers with optional deprecation .
3536enum Symbol < ' a > {
3637 Single ( char ) ,
37- Multi ( Vec < ( ModifierSet < & ' a str > , char ) > ) ,
38+ Multi ( Vec < ( ModifierSet < & ' a str > , char , Option < & ' a str > ) > ) ,
3839}
3940
4041/// A single line during parsing.
@@ -46,6 +47,15 @@ enum Line<'a> {
4647 ModuleEnd ,
4748 Symbol ( & ' a str , Option < char > ) ,
4849 Variant ( ModifierSet < & ' a str > , char ) ,
50+ Eof ,
51+ }
52+
53+ #[ derive( Debug , Copy , Clone ) ]
54+ enum Declaration < ' a > {
55+ ModuleStart ( & ' a str , Option < & ' a str > ) ,
56+ ModuleEnd ,
57+ Symbol ( & ' a str , Option < char > , Option < & ' a str > ) ,
58+ Variant ( ModifierSet < & ' a str > , char , Option < & ' a str > ) ,
4959}
5060
5161fn main ( ) {
@@ -66,11 +76,43 @@ fn process(buf: &mut String, file: &Path, name: &str, desc: &str) {
6676
6777 let text = std:: fs:: read_to_string ( file) . unwrap ( ) ;
6878 let mut line_nr = 0 ;
79+ let mut deprecation = None ;
6980 let mut iter = text
7081 . lines ( )
7182 . inspect ( |_| line_nr += 1 )
7283 . map ( tokenize)
73- . filter ( |line| !matches ! ( line, Ok ( Line :: Blank ) ) )
84+ . chain ( iter:: once ( Ok ( Line :: Eof ) ) )
85+ . filter_map ( |line| match line {
86+ Err ( message) => Some ( Err ( message) ) ,
87+ Ok ( Line :: Blank ) => None ,
88+ Ok ( Line :: Deprecated ( message) ) => {
89+ if deprecation. is_some ( ) {
90+ Some ( Err ( String :: from ( "duplicate `@deprecated:`" ) ) )
91+ } else {
92+ deprecation = Some ( message) ;
93+ None
94+ }
95+ }
96+ Ok ( Line :: ModuleStart ( name) ) => {
97+ Some ( Ok ( Declaration :: ModuleStart ( name, deprecation. take ( ) ) ) )
98+ }
99+ Ok ( Line :: ModuleEnd ) => {
100+ if deprecation. is_some ( ) {
101+ Some ( Err ( String :: from ( "dangling `@deprecated:`" ) ) )
102+ } else {
103+ Some ( Ok ( Declaration :: ModuleEnd ) )
104+ }
105+ }
106+ Ok ( Line :: Symbol ( name, c) ) => {
107+ Some ( Ok ( Declaration :: Symbol ( name, c, deprecation. take ( ) ) ) )
108+ }
109+ Ok ( Line :: Variant ( modifiers, c) ) => {
110+ Some ( Ok ( Declaration :: Variant ( modifiers, c, deprecation. take ( ) ) ) )
111+ }
112+ Ok ( Line :: Eof ) => {
113+ deprecation. map ( |_| Err ( String :: from ( "dangling `@deprecated:`" ) ) )
114+ }
115+ } )
74116 . peekable ( ) ;
75117
76118 let module = match parse ( & mut iter) {
@@ -150,29 +192,26 @@ fn decode_char(text: &str) -> StrResult<char> {
150192
151193/// Turns a stream of lines into a list of definitions.
152194fn parse < ' a > (
153- p : & mut Peekable < impl Iterator < Item = StrResult < Line < ' a > > > > ,
195+ p : & mut Peekable < impl Iterator < Item = StrResult < Declaration < ' a > > > > ,
154196) -> StrResult < Vec < ( & ' a str , Binding < ' a > ) > > {
155197 let mut defs = vec ! [ ] ;
156- let mut deprecation = None ;
157198 loop {
158199 match p. next ( ) . transpose ( ) ? {
159- None | Some ( Line :: ModuleEnd ) => {
160- if let Some ( message) = deprecation {
161- return Err ( format ! ( "dangling `@deprecated: {}`" , message) ) ;
162- }
200+ None | Some ( Declaration :: ModuleEnd ) => {
163201 break ;
164202 }
165- Some ( Line :: Deprecated ( message) ) => deprecation = Some ( message) ,
166- Some ( Line :: Symbol ( name, c) ) => {
203+ Some ( Declaration :: Symbol ( name, c, deprecation) ) => {
167204 let mut variants = vec ! [ ] ;
168- while let Some ( Line :: Variant ( name, c) ) = p. peek ( ) . cloned ( ) . transpose ( ) ? {
169- variants. push ( ( name, c) ) ;
205+ while let Some ( Declaration :: Variant ( name, c, deprecation) ) =
206+ p. peek ( ) . cloned ( ) . transpose ( ) ?
207+ {
208+ variants. push ( ( name, c, deprecation) ) ;
170209 p. next ( ) ;
171210 }
172211
173212 let symbol = if !variants. is_empty ( ) {
174213 if let Some ( c) = c {
175- variants. insert ( 0 , ( ModifierSet :: default ( ) , c) ) ;
214+ variants. insert ( 0 , ( ModifierSet :: default ( ) , c, None ) ) ;
176215 }
177216 Symbol :: Multi ( variants)
178217 } else {
@@ -181,9 +220,8 @@ fn parse<'a>(
181220 } ;
182221
183222 defs. push ( ( name, Binding { def : Def :: Symbol ( symbol) , deprecation } ) ) ;
184- deprecation = None ;
185223 }
186- Some ( Line :: ModuleStart ( name) ) => {
224+ Some ( Declaration :: ModuleStart ( name, deprecation ) ) => {
187225 let module_defs = parse ( p) ?;
188226 defs. push ( (
189227 name,
@@ -192,7 +230,6 @@ fn parse<'a>(
192230 deprecation,
193231 } ,
194232 ) ) ;
195- deprecation = None ;
196233 }
197234 other => return Err ( format ! ( "expected definition, found {other:?}" ) ) ,
198235 }
0 commit comments