@@ -533,28 +533,11 @@ impl fmt::Display for NormalizationForm {
533533pub struct EscapeQuotedString < ' a > {
534534 string : & ' a str ,
535535 quote : char ,
536+ always_escape_quote : bool ,
536537}
537538
538539impl fmt:: Display for EscapeQuotedString < ' _ > {
539540 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
540- // EscapeQuotedString doesn't know which mode of escape was
541- // chosen by the user. So this code must to correctly display
542- // strings without knowing if the strings are already escaped
543- // or not.
544- //
545- // If the quote symbol in the string is repeated twice, OR, if
546- // the quote symbol is after backslash, display all the chars
547- // without any escape. However, if the quote symbol is used
548- // just between usual chars, `fmt()` should display it twice."
549- //
550- // The following table has examples
551- //
552- // | original query | mode | AST Node | serialized |
553- // | ------------- | --------- | -------------------------------------------------- | ------------ |
554- // | `"A""B""A"` | no-escape | `DoubleQuotedString(String::from("A\"\"B\"\"A"))` | `"A""B""A"` |
555- // | `"A""B""A"` | default | `DoubleQuotedString(String::from("A\"B\"A"))` | `"A""B""A"` |
556- // | `"A\"B\"A"` | no-escape | `DoubleQuotedString(String::from("A\\\"B\\\"A"))` | `"A\"B\"A"` |
557- // | `"A\"B\"A"` | default | `DoubleQuotedString(String::from("A\"B\"A"))` | `"A""B""A"` |
558541 let quote = self . quote ;
559542 let mut previous_char = char:: default ( ) ;
560543 let mut start_idx = 0 ;
@@ -563,20 +546,15 @@ impl fmt::Display for EscapeQuotedString<'_> {
563546 match ch {
564547 char if char == quote => {
565548 if previous_char == '\\' {
566- // the quote is already escaped with a backslash, skip
567549 peekable_chars. next ( ) ;
568550 continue ;
569551 }
570552 peekable_chars. next ( ) ;
571553 match peekable_chars. peek ( ) {
572- Some ( ( _, c) ) if * c == quote => {
573- // the quote is already escaped with another quote, skip
554+ Some ( ( _, c) ) if !self . always_escape_quote && * c == quote => {
574555 peekable_chars. next ( ) ;
575556 }
576557 _ => {
577- // The quote is not escaped.
578- // Including idx in the range, so the quote at idx will be printed twice:
579- // in this call to write_str() and in the next one.
580558 let end_idx = idx + ch. len_utf8 ( ) ;
581559 f. write_str ( & self . string [ start_idx..end_idx] ) ?;
582560 start_idx = idx;
@@ -597,12 +575,20 @@ impl fmt::Display for EscapeQuotedString<'_> {
597575/// Return a helper which formats `string` for inclusion inside a quoted
598576/// literal that uses `quote` as the delimiter.
599577pub fn escape_quoted_string ( string : & str , quote : char ) -> EscapeQuotedString < ' _ > {
600- EscapeQuotedString { string, quote }
578+ EscapeQuotedString {
579+ string,
580+ quote,
581+ always_escape_quote : false ,
582+ }
601583}
602584
603585/// Convenience wrapper for escaping strings for single-quoted literals (`'`).
604586pub fn escape_single_quote_string ( s : & str ) -> EscapeQuotedString < ' _ > {
605- escape_quoted_string ( s, '\'' )
587+ EscapeQuotedString {
588+ string : s,
589+ quote : '\'' ,
590+ always_escape_quote : true ,
591+ }
606592}
607593
608594/// Convenience wrapper for escaping strings for double-quoted literals (`").`
0 commit comments