@@ -67,25 +67,35 @@ impl FStringParser {
6767 Some ( 'a' ) => ConversionFlag :: Ascii ,
6868 Some ( 'r' ) => ConversionFlag :: Repr ,
6969 Some ( _) => {
70- return Err ( InvalidConversionFlag ) ;
70+ return Err ( if expression[ 1 ..] . trim ( ) . is_empty ( ) {
71+ EmptyExpression
72+ } else {
73+ InvalidConversionFlag
74+ } ) ;
7175 }
7276 None => {
73- return Err ( ExpectedRbrace ) ;
77+ return Err ( if expression[ 1 ..] . trim ( ) . is_empty ( ) {
78+ EmptyExpression
79+ } else {
80+ UnclosedLbrace
81+ } ) ;
7482 }
7583 } ;
7684
7785 if let Some ( & peek) = chars. peek ( ) {
7886 if peek != '}' && peek != ':' {
79- if expression[ 1 ..] . trim ( ) . is_empty ( ) {
80- return Err ( EmptyExpression ) ;
87+ return Err ( if expression[ 1 ..] . trim ( ) . is_empty ( ) {
88+ EmptyExpression
8189 } else {
82- return Err ( ExpectedRbrace ) ;
83- }
90+ UnclosedLbrace
91+ } ) ;
8492 }
85- } else if expression[ 1 ..] . trim ( ) . is_empty ( ) {
86- return Err ( EmptyExpression ) ;
8793 } else {
88- return Err ( ExpectedRbrace ) ;
94+ return Err ( if expression[ 1 ..] . trim ( ) . is_empty ( ) {
95+ EmptyExpression
96+ } else {
97+ UnclosedLbrace
98+ } ) ;
8999 }
90100 }
91101
@@ -108,22 +118,42 @@ impl FStringParser {
108118 delims. push ( ch) ;
109119 }
110120 ')' => {
111- if delims. pop ( ) != Some ( '(' ) {
112- return Err ( MismatchedDelimiter ) ;
121+ let last_delim = delims. pop ( ) ;
122+ match last_delim {
123+ Some ( '(' ) => {
124+ expression. push ( ch) ;
125+ }
126+ Some ( c) => {
127+ return Err ( MismatchedDelimiter ( c, ')' ) ) ;
128+ }
129+ None => {
130+ return Err ( Unmatched ( ')' ) ) ;
131+ }
113132 }
114- expression. push ( ch) ;
115133 }
116134 ']' => {
117- if delims. pop ( ) != Some ( '[' ) {
118- return Err ( MismatchedDelimiter ) ;
135+ let last_delim = delims. pop ( ) ;
136+ match last_delim {
137+ Some ( '[' ) => {
138+ expression. push ( ch) ;
139+ }
140+ Some ( c) => {
141+ return Err ( MismatchedDelimiter ( c, ']' ) ) ;
142+ }
143+ None => {
144+ return Err ( Unmatched ( ']' ) ) ;
145+ }
119146 }
120- expression. push ( ch) ;
121147 }
122148 '}' if !delims. is_empty ( ) => {
123- if delims. pop ( ) != Some ( '{' ) {
124- return Err ( MismatchedDelimiter ) ;
149+ let last_delim = delims. pop ( ) ;
150+ match last_delim {
151+ Some ( '{' ) => {
152+ expression. push ( ch) ;
153+ }
154+ Some ( c) => return Err ( MismatchedDelimiter ( c, '}' ) ) ,
155+ None => { }
125156 }
126- expression. push ( ch) ;
127157 }
128158 '}' => {
129159 if expression[ 1 ..] . trim ( ) . is_empty ( ) {
@@ -171,26 +201,36 @@ impl FStringParser {
171201 }
172202 '"' | '\'' => {
173203 expression. push ( ch) ;
204+ let mut string_ended = false ;
174205 for next in & mut chars {
175206 expression. push ( next) ;
176207 if next == ch {
208+ string_ended = true ;
177209 break ;
178210 }
179211 }
212+ if !string_ended {
213+ return Err ( UnterminatedString ) ;
214+ }
180215 }
181216 ' ' if self_documenting => {
182217 trailing_seq. push ( ch) ;
183218 }
219+ '\\' => return Err ( ExpressionCannotInclude ( '\\' ) ) ,
184220 _ => {
185221 if self_documenting {
186- return Err ( ExpectedRbrace ) ;
222+ return Err ( UnclosedLbrace ) ;
187223 }
188224
189225 expression. push ( ch) ;
190226 }
191227 }
192228 }
193- Err ( UnclosedLbrace )
229+ Err ( if expression[ 1 ..] . trim ( ) . is_empty ( ) {
230+ EmptyExpression
231+ } else {
232+ UnclosedLbrace
233+ } )
194234 }
195235
196236 fn parse_spec < ' a > (
@@ -251,10 +291,14 @@ impl FStringParser {
251291 '{' => {
252292 chars. next ( ) ;
253293 if nested == 0 {
254- if let Some ( '{' ) = chars. peek ( ) {
255- chars. next ( ) ;
256- content. push ( '{' ) ;
257- continue ;
294+ match chars. peek ( ) {
295+ Some ( '{' ) => {
296+ chars. next ( ) ;
297+ content. push ( '{' ) ;
298+ continue ;
299+ }
300+ None => return Err ( UnclosedLbrace ) ,
301+ _ => { }
258302 }
259303 }
260304 if !content. is_empty ( ) {
@@ -278,7 +322,7 @@ impl FStringParser {
278322 chars. next ( ) ;
279323 content. push ( '}' ) ;
280324 } else {
281- return Err ( UnopenedRbrace ) ;
325+ return Err ( SingleRbrace ) ;
282326 }
283327 }
284328 _ => {
@@ -385,9 +429,9 @@ mod tests {
385429
386430 #[ test]
387431 fn test_parse_invalid_fstring ( ) {
388- assert_eq ! ( parse_fstring( "{5!a" ) , Err ( ExpectedRbrace ) ) ;
389- assert_eq ! ( parse_fstring( "{5!a1}" ) , Err ( ExpectedRbrace ) ) ;
390- assert_eq ! ( parse_fstring( "{5!" ) , Err ( ExpectedRbrace ) ) ;
432+ assert_eq ! ( parse_fstring( "{5!a" ) , Err ( UnclosedLbrace ) ) ;
433+ assert_eq ! ( parse_fstring( "{5!a1}" ) , Err ( UnclosedLbrace ) ) ;
434+ assert_eq ! ( parse_fstring( "{5!" ) , Err ( UnclosedLbrace ) ) ;
391435 assert_eq ! ( parse_fstring( "abc{!a 'cat'}" ) , Err ( EmptyExpression ) ) ;
392436 assert_eq ! ( parse_fstring( "{!a" ) , Err ( EmptyExpression ) ) ;
393437 assert_eq ! ( parse_fstring( "{ !a}" ) , Err ( EmptyExpression ) ) ;
@@ -397,8 +441,8 @@ mod tests {
397441
398442 assert_eq ! ( parse_fstring( "{a:{a:{b}}}" ) , Err ( ExpressionNestedTooDeeply ) ) ;
399443
400- assert_eq ! ( parse_fstring( "{a:b}}" ) , Err ( UnopenedRbrace ) ) ;
401- assert_eq ! ( parse_fstring( "}" ) , Err ( UnopenedRbrace ) ) ;
444+ assert_eq ! ( parse_fstring( "{a:b}}" ) , Err ( SingleRbrace ) ) ;
445+ assert_eq ! ( parse_fstring( "}" ) , Err ( SingleRbrace ) ) ;
402446 assert_eq ! ( parse_fstring( "{a:{b}" ) , Err ( UnclosedLbrace ) ) ;
403447 assert_eq ! ( parse_fstring( "{" ) , Err ( UnclosedLbrace ) ) ;
404448
0 commit comments