@@ -62,14 +62,15 @@ impl InterpolableFragment {
6262
6363 fn balance_single_quotes ( & mut self ) {
6464 let mut in_single_quotes = false ;
65+ let mut in_double_quotes = false ;
6566
6667 for s in & mut self . strings {
6768 // If previous chunk left us inside quotes, reopen at the start.
6869 if in_single_quotes {
6970 s. insert_str ( 0 , "\" '" ) ;
7071 }
7172
72- let unescaped = count_unescaped_single_quotes ( s ) ;
73+ let unescaped = count_single_quotes ( s , & mut in_double_quotes ) ;
7374
7475 // If this chunk has an odd number of unescaped quotes, it toggles the region.
7576 if unescaped % 2 == 1 {
@@ -103,15 +104,21 @@ impl InterpolableFragment {
103104}
104105
105106/// Count single quotes that are NOT escaped by an odd number of preceding backslashes.
106- fn count_unescaped_single_quotes ( s : & str ) -> usize {
107+ fn count_single_quotes ( s : & str , in_double_quotes : & mut bool ) -> usize {
107108 let mut count = 0usize ;
108109 let mut backslashes = 0usize ;
109110
110111 for b in s. bytes ( ) {
111112 match b {
112113 b'\\' => backslashes += 1 ,
113- b'\' ' => {
114+ b'" ' => {
114115 if backslashes % 2 == 0 {
116+ * in_double_quotes = !* in_double_quotes;
117+ }
118+ backslashes = 0 ;
119+ }
120+ b'\'' => {
121+ if !* in_double_quotes && backslashes % 2 == 0 {
115122 count += 1 ;
116123 }
117124 backslashes = 0 ;
@@ -180,12 +187,33 @@ mod tests {
180187
181188 #[ test]
182189 fn test_count_unescaped_single_quotes ( ) {
183- assert_eq ! ( count_unescaped_single_quotes( r#"foo"# ) , 0 ) ;
184- assert_eq ! ( count_unescaped_single_quotes( r#"foo\'bar"# ) , 0 ) ;
185- assert_eq ! ( count_unescaped_single_quotes( r#"foo'bar"# ) , 1 ) ;
190+ let mut in_dq;
191+ in_dq = false ; assert_eq ! ( count_single_quotes( r#"foo"# , & mut in_dq) , 0 ) ;
192+ in_dq = false ; assert_eq ! ( count_single_quotes( r#"foo\'bar"# , & mut in_dq) , 0 ) ;
193+ in_dq = false ; assert_eq ! ( count_single_quotes( r#"foo'bar"# , & mut in_dq) , 1 ) ;
186194 // even number of backslashes before quote -> not escaped
187- assert_eq ! ( count_unescaped_single_quotes( r#"foo\\\\'bar"# ) , 1 ) ;
188- assert_eq ! ( count_unescaped_single_quotes( r#"'\"'"# ) , 2 ) ;
189- assert_eq ! ( count_unescaped_single_quotes( r#"'''"# ) , 3 ) ;
195+ in_dq = false ; assert_eq ! ( count_single_quotes( r#"foo\\\\'bar"# , & mut in_dq) , 1 ) ;
196+ in_dq = false ; assert_eq ! ( count_single_quotes( r#"'"# , & mut in_dq) , 1 ) ;
197+ in_dq = false ; assert_eq ! ( count_single_quotes( r#"'\"'"# , & mut in_dq) , 2 ) ;
198+ in_dq = false ; assert_eq ! ( count_single_quotes( r#"'''"# , & mut in_dq) , 3 ) ;
199+ in_dq = false ; assert_eq ! ( count_single_quotes( r#""'""# , & mut in_dq) , 0 ) ;
200+
201+ in_dq = false ;
202+ assert_eq ! ( count_single_quotes( r#"'""# , & mut in_dq) , 1 ) ;
203+ assert ! ( in_dq) ;
204+ assert_eq ! ( count_single_quotes( r#"'""# , & mut in_dq) , 0 ) ;
205+ assert ! ( !in_dq) ;
206+ assert_eq ! ( count_single_quotes( r#"\"'\""# , & mut in_dq) , 1 ) ;
207+ assert ! ( !in_dq) ;
208+ assert_eq ! ( count_single_quotes( r#"""# , & mut in_dq) , 0 ) ;
209+ assert ! ( in_dq) ;
210+ assert_eq ! ( count_single_quotes( r#"'"# , & mut in_dq) , 0 ) ;
211+ assert ! ( in_dq) ;
212+ assert_eq ! ( count_single_quotes( r#"\'"# , & mut in_dq) , 0 ) ;
213+ assert ! ( in_dq) ;
214+ assert_eq ! ( count_single_quotes( r#"\""# , & mut in_dq) , 0 ) ;
215+ assert ! ( in_dq) ;
216+ assert_eq ! ( count_single_quotes( r#"""# , & mut in_dq) , 0 ) ;
217+ assert ! ( !in_dq) ;
190218 }
191219}
0 commit comments