@@ -58,6 +58,42 @@ pub enum EscapeError {
58
58
NonAsciiCharInByteString ,
59
59
}
60
60
61
+ /// Takes a contents of a literal (without quotes) and produces a
62
+ /// sequence of escaped characters or errors.
63
+ /// Values are returned through invoking of the provided callback.
64
+ pub fn unescape_literal < F > ( literal_text : & str , mode : Mode , callback : & mut F )
65
+ where
66
+ F : FnMut ( Range < usize > , Result < char , EscapeError > ) ,
67
+ {
68
+ match mode {
69
+ Mode :: Char | Mode :: Byte => {
70
+ let mut chars = literal_text. chars ( ) ;
71
+ let result = unescape_char_or_byte ( & mut chars, mode) ;
72
+ // The Chars iterator moved forward.
73
+ callback ( 0 ..( literal_text. len ( ) - chars. as_str ( ) . len ( ) ) , result) ;
74
+ }
75
+ Mode :: Str | Mode :: ByteStr => unescape_str_or_byte_str ( literal_text, mode, callback) ,
76
+ // NOTE: Raw strings do not perform any explicit character escaping, here we
77
+ // only translate CRLF to LF and produce errors on bare CR.
78
+ Mode :: RawStr | Mode :: RawByteStr => {
79
+ unescape_raw_str_or_byte_str ( literal_text, mode, callback)
80
+ }
81
+ }
82
+ }
83
+
84
+ /// Takes a contents of a byte, byte string or raw byte string (without quotes)
85
+ /// and produces a sequence of bytes or errors.
86
+ /// Values are returned through invoking of the provided callback.
87
+ pub fn unescape_byte_literal < F > ( literal_text : & str , mode : Mode , callback : & mut F )
88
+ where
89
+ F : FnMut ( Range < usize > , Result < u8 , EscapeError > ) ,
90
+ {
91
+ assert ! ( mode. is_bytes( ) ) ;
92
+ unescape_literal ( literal_text, mode, & mut |range, result| {
93
+ callback ( range, result. map ( byte_from_char) ) ;
94
+ } )
95
+ }
96
+
61
97
/// Takes a contents of a char literal (without quotes), and returns an
62
98
/// unescaped char or an error
63
99
pub fn unescape_char ( literal_text : & str ) -> Result < char , ( usize , EscapeError ) > {
@@ -130,13 +166,15 @@ pub enum Mode {
130
166
Str ,
131
167
Byte ,
132
168
ByteStr ,
169
+ RawStr ,
170
+ RawByteStr ,
133
171
}
134
172
135
173
impl Mode {
136
174
pub fn in_single_quotes ( self ) -> bool {
137
175
match self {
138
176
Mode :: Char | Mode :: Byte => true ,
139
- Mode :: Str | Mode :: ByteStr => false ,
177
+ Mode :: Str | Mode :: ByteStr | Mode :: RawStr | Mode :: RawByteStr => false ,
140
178
}
141
179
}
142
180
@@ -146,8 +184,8 @@ impl Mode {
146
184
147
185
pub fn is_bytes ( self ) -> bool {
148
186
match self {
149
- Mode :: Byte | Mode :: ByteStr => true ,
150
- Mode :: Char | Mode :: Str => false ,
187
+ Mode :: Byte | Mode :: ByteStr | Mode :: RawByteStr => true ,
188
+ Mode :: Char | Mode :: Str | Mode :: RawStr => false ,
151
189
}
152
190
}
153
191
}
@@ -345,7 +383,7 @@ where
345
383
346
384
fn byte_from_char ( c : char ) -> u8 {
347
385
let res = c as u32 ;
348
- assert ! ( res <= u8 :: max_value( ) as u32 , "guaranteed because of Mode::Byte(Str) " ) ;
386
+ assert ! ( res <= u8 :: max_value( ) as u32 , "guaranteed because of Mode::ByteStr " ) ;
349
387
res as u8
350
388
}
351
389
0 commit comments