@@ -7,37 +7,41 @@ use std::fmt;
77
88use unicode_segmentation:: UnicodeSegmentation ;
99
10+ #[ inline( always) ]
11+ fn escape ( s : & str , mut w : impl fmt:: Write , escape_quotes : bool ) -> fmt:: Result {
12+ // Because the internet is always right, turns out there's not that many
13+ // characters to escape: http://stackoverflow.com/questions/7381974
14+ let pile_o_bits = s;
15+ let mut last = 0 ;
16+ for ( i, ch) in s. char_indices ( ) {
17+ let s = match ch {
18+ '>' => ">" ,
19+ '<' => "<" ,
20+ '&' => "&" ,
21+ '\'' if escape_quotes => "'" ,
22+ '"' if escape_quotes => """ ,
23+ _ => continue ,
24+ } ;
25+ w. write_str ( & pile_o_bits[ last..i] ) ?;
26+ w. write_str ( s) ?;
27+ // NOTE: we only expect single byte characters here - which is fine as long as we
28+ // only match single byte characters
29+ last = i + 1 ;
30+ }
31+
32+ if last < s. len ( ) {
33+ w. write_str ( & pile_o_bits[ last..] ) ?;
34+ }
35+ Ok ( ( ) )
36+ }
37+
1038/// Wrapper struct which will emit the HTML-escaped version of the contained
1139/// string when passed to a format string.
1240pub ( crate ) struct Escape < ' a > ( pub & ' a str ) ;
1341
1442impl fmt:: Display for Escape < ' _ > {
1543 fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
16- // Because the internet is always right, turns out there's not that many
17- // characters to escape: http://stackoverflow.com/questions/7381974
18- let Escape ( s) = * self ;
19- let pile_o_bits = s;
20- let mut last = 0 ;
21- for ( i, ch) in s. char_indices ( ) {
22- let s = match ch {
23- '>' => ">" ,
24- '<' => "<" ,
25- '&' => "&" ,
26- '\'' => "'" ,
27- '"' => """ ,
28- _ => continue ,
29- } ;
30- fmt. write_str ( & pile_o_bits[ last..i] ) ?;
31- fmt. write_str ( s) ?;
32- // NOTE: we only expect single byte characters here - which is fine as long as we
33- // only match single byte characters
34- last = i + 1 ;
35- }
36-
37- if last < s. len ( ) {
38- fmt. write_str ( & pile_o_bits[ last..] ) ?;
39- }
40- Ok ( ( ) )
44+ escape ( self . 0 , fmt, true )
4145 }
4246}
4347
@@ -51,29 +55,7 @@ pub(crate) struct EscapeBodyText<'a>(pub &'a str);
5155
5256impl fmt:: Display for EscapeBodyText < ' _ > {
5357 fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
54- // Because the internet is always right, turns out there's not that many
55- // characters to escape: http://stackoverflow.com/questions/7381974
56- let EscapeBodyText ( s) = * self ;
57- let pile_o_bits = s;
58- let mut last = 0 ;
59- for ( i, ch) in s. char_indices ( ) {
60- let s = match ch {
61- '>' => ">" ,
62- '<' => "<" ,
63- '&' => "&" ,
64- _ => continue ,
65- } ;
66- fmt. write_str ( & pile_o_bits[ last..i] ) ?;
67- fmt. write_str ( s) ?;
68- // NOTE: we only expect single byte characters here - which is fine as long as we
69- // only match single byte characters
70- last = i + 1 ;
71- }
72-
73- if last < s. len ( ) {
74- fmt. write_str ( & pile_o_bits[ last..] ) ?;
75- }
76- Ok ( ( ) )
58+ escape ( self . 0 , fmt, false )
7759 }
7860}
7961
0 commit comments