@@ -863,17 +863,54 @@ impl FormatString {
863
863
}
864
864
865
865
fn parse_part_in_brackets ( text : & str ) -> Result < FormatPart , FormatParseError > {
866
- let parts: Vec < & str > = text. splitn ( 2 , ':' ) . collect ( ) ;
866
+ let mut chars = text. chars ( ) . peekable ( ) ;
867
+
868
+ let mut left = String :: new ( ) ;
869
+ let mut right = String :: new ( ) ;
870
+
871
+ let mut split = false ;
872
+ let mut inside_brackets = false ;
873
+
874
+ while let Some ( char) = chars. next ( ) {
875
+ if char == '[' {
876
+ inside_brackets = true ;
877
+
878
+ if split {
879
+ right. push ( char) ;
880
+ } else {
881
+ left. push ( char) ;
882
+ }
883
+
884
+ while let Some ( next_char) = chars. next ( ) {
885
+ if split {
886
+ right. push ( next_char) ;
887
+ } else {
888
+ left. push ( next_char) ;
889
+ }
890
+
891
+ if next_char == ']' {
892
+ inside_brackets = false ;
893
+ break ;
894
+ }
895
+ if chars. peek ( ) . is_none ( ) {
896
+ return Err ( FormatParseError :: MissingRightBracket ) ;
897
+ }
898
+ }
899
+ } else if char == ':' && !split && !inside_brackets {
900
+ split = true ;
901
+ } else if split {
902
+ right. push ( char) ;
903
+ } else {
904
+ left. push ( char) ;
905
+ }
906
+ }
907
+
867
908
// before the comma is a keyword or arg index, after the comma is maybe a spec.
868
- let arg_part = parts [ 0 ] ;
909
+ let arg_part: & str = & left ;
869
910
870
- let format_spec = if parts. len ( ) > 1 {
871
- parts[ 1 ] . to_owned ( )
872
- } else {
873
- String :: new ( )
874
- } ;
911
+ let format_spec = if split { right } else { String :: new ( ) } ;
875
912
876
- // On parts[0] can still be the conversion (!r, !s, !a)
913
+ // left can still be the conversion (!r, !s, !a)
877
914
let parts: Vec < & str > = arg_part. splitn ( 2 , '!' ) . collect ( ) ;
878
915
// before the bang is a keyword or arg index, after the comma is maybe a conversion spec.
879
916
let arg_part = parts[ 0 ] ;
@@ -1168,6 +1205,34 @@ mod tests {
1168
1205
) ;
1169
1206
}
1170
1207
1208
+ #[ test]
1209
+ fn test_square_brackets_inside_format ( ) {
1210
+ assert_eq ! (
1211
+ FormatString :: from_str( "{[:123]}" ) ,
1212
+ Ok ( FormatString {
1213
+ format_parts: vec![ FormatPart :: Field {
1214
+ field_name: "[:123]" . to_owned( ) ,
1215
+ conversion_spec: None ,
1216
+ format_spec: "" . to_owned( ) ,
1217
+ } ] ,
1218
+ } ) ,
1219
+ ) ;
1220
+
1221
+ assert_eq ! ( FormatString :: from_str( "{asdf[:123]asdf}" ) , {
1222
+ Ok ( FormatString {
1223
+ format_parts: vec![ FormatPart :: Field {
1224
+ field_name: "asdf[:123]asdf" . to_owned( ) ,
1225
+ conversion_spec: None ,
1226
+ format_spec: "" . to_owned( ) ,
1227
+ } ] ,
1228
+ } )
1229
+ } ) ;
1230
+
1231
+ assert_eq ! ( FormatString :: from_str( "{[1234}" ) , {
1232
+ Err ( FormatParseError :: MissingRightBracket )
1233
+ } ) ;
1234
+ }
1235
+
1171
1236
#[ test]
1172
1237
fn test_format_parse_escape ( ) {
1173
1238
let expected = Ok ( FormatString {
0 commit comments