@@ -58,6 +58,42 @@ pub enum EscapeError {
5858 NonAsciiCharInByteString ,
5959}
6060
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+
6197/// Takes a contents of a char literal (without quotes), and returns an
6298/// unescaped char or an error
6399pub fn unescape_char ( literal_text : & str ) -> Result < char , ( usize , EscapeError ) > {
@@ -130,13 +166,15 @@ pub enum Mode {
130166 Str ,
131167 Byte ,
132168 ByteStr ,
169+ RawStr ,
170+ RawByteStr ,
133171}
134172
135173impl Mode {
136174 pub fn in_single_quotes ( self ) -> bool {
137175 match self {
138176 Mode :: Char | Mode :: Byte => true ,
139- Mode :: Str | Mode :: ByteStr => false ,
177+ Mode :: Str | Mode :: ByteStr | Mode :: RawStr | Mode :: RawByteStr => false ,
140178 }
141179 }
142180
@@ -146,8 +184,8 @@ impl Mode {
146184
147185 pub fn is_bytes ( self ) -> bool {
148186 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 ,
151189 }
152190 }
153191}
@@ -345,7 +383,7 @@ where
345383
346384fn byte_from_char ( c : char ) -> u8 {
347385 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 " ) ;
349387 res as u8
350388}
351389
0 commit comments