@@ -4,6 +4,7 @@ use crate::{
44 error:: { FStringError , FStringErrorType , ParseError } ,
55 parser:: parse_expression,
66} ;
7+ use itertools:: Itertools ;
78use std:: { iter, mem, str} ;
89
910struct FStringParser < ' a > {
@@ -105,19 +106,16 @@ impl<'a> FStringParser<'a> {
105106 nested -= 1 ;
106107 if nested == 0 {
107108 formatted_value_piece. push ( next) ;
108- spec_constructor. push (
109- self . expr ( ExprKind :: FormattedValue {
110- value : Box :: new (
111- FStringParser :: new (
112- & formatted_value_piece,
113- Location :: default ( ) ,
114- & self . recurse_lvl + 1 ,
115- )
116- . parse ( ) ?,
117- ) ,
118- conversion : ConversionFlag :: None as _ ,
119- format_spec : None ,
120- } ) ,
109+ let values = FStringParser :: new (
110+ & formatted_value_piece,
111+ Location :: default ( ) ,
112+ & self . recurse_lvl + 1 ,
113+ )
114+ . parse ( ) ?;
115+ spec_constructor. push ( values
116+ . into_iter ( )
117+ . exactly_one ( )
118+ . expect ( "Expected formatted value to produce exactly one expression." )
121119 ) ;
122120 formatted_value_piece. clear ( ) ;
123121 } else {
@@ -129,11 +127,13 @@ impl<'a> FStringParser<'a> {
129127 }
130128 '{' => {
131129 nested += 1 ;
132- spec_constructor. push ( self . expr ( ExprKind :: Constant {
133- value : constant_piece. to_owned ( ) . into ( ) ,
134- kind : None ,
135- } ) ) ;
136- constant_piece. clear ( ) ;
130+ if !constant_piece. is_empty ( ) {
131+ spec_constructor. push ( self . expr ( ExprKind :: Constant {
132+ value : constant_piece. to_owned ( ) . into ( ) ,
133+ kind : None ,
134+ } ) ) ;
135+ constant_piece. clear ( ) ;
136+ }
137137 formatted_value_piece. push ( next) ;
138138 formatted_value_piece. push ( ' ' ) ;
139139 }
@@ -144,11 +144,13 @@ impl<'a> FStringParser<'a> {
144144 }
145145 self . chars . next ( ) ;
146146 }
147- spec_constructor. push ( self . expr ( ExprKind :: Constant {
148- value : constant_piece. to_owned ( ) . into ( ) ,
149- kind : None ,
150- } ) ) ;
151- constant_piece. clear ( ) ;
147+ if !constant_piece. is_empty ( ) {
148+ spec_constructor. push ( self . expr ( ExprKind :: Constant {
149+ value : constant_piece. to_owned ( ) . into ( ) ,
150+ kind : None ,
151+ } ) ) ;
152+ constant_piece. clear ( ) ;
153+ }
152154 if nested > 0 {
153155 return Err ( UnclosedLbrace ) ;
154156 }
@@ -241,7 +243,7 @@ impl<'a> FStringParser<'a> {
241243 Err ( UnclosedLbrace )
242244 }
243245
244- fn parse ( mut self ) -> Result < Expr , FStringErrorType > {
246+ fn parse ( mut self ) -> Result < Vec < Expr > , FStringErrorType > {
245247 if self . recurse_lvl >= 2 {
246248 return Err ( ExpressionNestedTooDeeply ) ;
247249 }
@@ -287,7 +289,7 @@ impl<'a> FStringParser<'a> {
287289 } ) )
288290 }
289291
290- Ok ( self . expr ( ExprKind :: JoinedStr { values } ) )
292+ Ok ( values)
291293 }
292294}
293295
@@ -298,7 +300,7 @@ fn parse_fstring_expr(source: &str) -> Result<Expr, ParseError> {
298300
299301/// Parse an fstring from a string, located at a certain position in the sourcecode.
300302/// In case of errors, we will get the location and the error returned.
301- pub fn parse_located_fstring ( source : & str , location : Location ) -> Result < Expr , FStringError > {
303+ pub fn parse_located_fstring ( source : & str , location : Location ) -> Result < Vec < Expr > , FStringError > {
302304 FStringParser :: new ( source, location, 0 )
303305 . parse ( )
304306 . map_err ( |error| FStringError { error, location } )
@@ -308,7 +310,7 @@ pub fn parse_located_fstring(source: &str, location: Location) -> Result<Expr, F
308310mod tests {
309311 use super :: * ;
310312
311- fn parse_fstring ( source : & str ) -> Result < Expr , FStringErrorType > {
313+ fn parse_fstring ( source : & str ) -> Result < Vec < Expr > , FStringErrorType > {
312314 FStringParser :: new ( source, Location :: default ( ) , 0 ) . parse ( )
313315 }
314316
0 commit comments