@@ -863,17 +863,56 @@ 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 ( ) == None {
896
+ return Err ( FormatParseError :: MissingRightBracket ) ;
897
+ }
898
+ }
899
+ } else if char == ':' && split == false && inside_brackets == false {
900
+ split = true ;
901
+ } else {
902
+ if split {
903
+ right. push ( char) ;
904
+ } else {
905
+ left. push ( char) ;
906
+ }
907
+ }
908
+ }
909
+
867
910
// before the comma is a keyword or arg index, after the comma is maybe a spec.
868
- let arg_part = parts [ 0 ] ;
911
+ let arg_part: & str = & left ;
869
912
870
- let format_spec = if parts. len ( ) > 1 {
871
- parts[ 1 ] . to_owned ( )
872
- } else {
873
- String :: new ( )
874
- } ;
913
+ let format_spec = if split { right } else { String :: new ( ) } ;
875
914
876
- // On parts[0] can still be the conversion (!r, !s, !a)
915
+ // left can still be the conversion (!r, !s, !a)
877
916
let parts: Vec < & str > = arg_part. splitn ( 2 , '!' ) . collect ( ) ;
878
917
// before the bang is a keyword or arg index, after the comma is maybe a conversion spec.
879
918
let arg_part = parts[ 0 ] ;
@@ -1168,6 +1207,34 @@ mod tests {
1168
1207
) ;
1169
1208
}
1170
1209
1210
+ #[ test]
1211
+ fn test_square_braces_inside_format ( ) {
1212
+ assert_eq ! (
1213
+ FormatString :: from_str( "{[:123]}" ) ,
1214
+ Ok ( FormatString {
1215
+ format_parts: vec![ FormatPart :: Field {
1216
+ field_name: "[:123]" . to_owned( ) ,
1217
+ conversion_spec: None ,
1218
+ format_spec: "" . to_owned( ) ,
1219
+ } ] ,
1220
+ } ) ,
1221
+ ) ;
1222
+
1223
+ assert_eq ! ( FormatString :: from_str( "{asdf[:123]asdf}" ) , {
1224
+ Ok ( FormatString {
1225
+ format_parts: vec![ FormatPart :: Field {
1226
+ field_name: "asdf[:123]asdf" . to_owned( ) ,
1227
+ conversion_spec: None ,
1228
+ format_spec: "" . to_owned( ) ,
1229
+ } ] ,
1230
+ } )
1231
+ } ) ;
1232
+
1233
+ assert_eq ! ( FormatString :: from_str( "{[1234}" ) , {
1234
+ Err ( FormatParseError :: MissingRightBracket )
1235
+ } ) ;
1236
+ }
1237
+
1171
1238
#[ test]
1172
1239
fn test_format_parse_escape ( ) {
1173
1240
let expected = Ok ( FormatString {
0 commit comments