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