@@ -141,25 +141,41 @@ pub enum LiteralKind {
141141 RawByteStr ( UnvalidatedRawStr ) ,
142142}
143143
144+ /// Represents something that looks like a raw string, but may have some
145+ /// problems. Use `.validate()` to convert it into something
146+ /// usable.
144147#[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord ) ]
145148pub struct UnvalidatedRawStr {
149+ /// The prefix (`r###"`) is valid
146150 valid_start : bool ,
151+ /// The number of leading `#`
147152 n_start_hashes : usize ,
153+ /// The number of trailing `#`. `n_end_hashes` <= `n_start_hashes`
148154 n_end_hashes : usize ,
155+ /// The offset starting at `r` or `br` where the user may have intended to end the string.
156+ /// Currently, it is the longest sequence of pattern `"#+"`.
149157 possible_terminator_offset : Option < usize > ,
150158}
151159
160+ /// Error produced validating a raw string. Represents cases like:
161+ /// - `r##~"abcde"##`: `LexRawStrError::InvalidStarter`
162+ /// - `r###"abcde"##`: `LexRawStrError::NoTerminator { expected: 3, found: 2, possible_terminator_offset: Some(11)`
163+ /// - Too many `#`s (>65536): `TooManyDelimiters`
152164#[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord ) ]
153165pub enum LexRawStrError {
154- /// Non # characters between `r` and `"` eg. `r#~"..`
166+ /// Non `#` characters exist between `r` and `"` eg. `r#~"..`
155167 InvalidStarter ,
156- /// The string was never terminated. `possible_terminator_offset` is the best guess of where they
168+ /// The string was never terminated. `possible_terminator_offset` is the number of characters after `r` or `br` where they
157169 /// may have intended to terminate it.
158170 NoTerminator { expected : usize , found : usize , possible_terminator_offset : Option < usize > } ,
159- /// More than 65536 # signs
171+ /// More than 65536 `#`s exist.
160172 TooManyDelimiters ,
161173}
162174
175+ /// Raw String that contains a valid prefix (`#+"`) and postfix (`"#+`) where
176+ /// there are a matching number of `#` characters in both. Note that this will
177+ /// not consume extra trailing `#` characters: `r###"abcde"####` is lexed as a
178+ /// `ValidatedRawString { n_hashes: 3 }` followed by a `#` token.
163179#[ derive( Debug , Eq , PartialEq , Copy , Clone ) ]
164180pub struct ValidatedRawStr {
165181 n_hashes : u16 ,
@@ -172,27 +188,26 @@ impl ValidatedRawStr {
172188}
173189
174190impl UnvalidatedRawStr {
175- pub fn started ( & self ) -> bool {
176- self . valid_start
177- }
178-
179191 pub fn validate ( self ) -> Result < ValidatedRawStr , LexRawStrError > {
180192 if !self . valid_start {
181193 return Err ( LexRawStrError :: InvalidStarter ) ;
182194 }
183195
196+ // Only up to 65535 `#`s are allowed in raw strings
184197 let n_start_safe: u16 =
185198 self . n_start_hashes . try_into ( ) . map_err ( |_| LexRawStrError :: TooManyDelimiters ) ?;
186- match ( self . n_start_hashes , self . n_end_hashes ) {
187- ( n_start, n_end) if n_start > n_end => Err ( LexRawStrError :: NoTerminator {
188- expected : n_start,
199+
200+ if self . n_start_hashes > self . n_end_hashes {
201+ Err ( LexRawStrError :: NoTerminator {
202+ expected : self . n_start_hashes ,
189203 found : self . n_end_hashes ,
190204 possible_terminator_offset : self . possible_terminator_offset ,
191- } ) ,
192- ( n_start, n_end) => {
193- debug_assert_eq ! ( n_start, n_end) ;
194- Ok ( ValidatedRawStr { n_hashes : n_start_safe } )
195- }
205+ } )
206+ } else {
207+ // Since the lexer should never produce a literal with n_end > n_start, if n_start <= n_end,
208+ // they must be equal.
209+ debug_assert_eq ! ( self . n_start_hashes, self . n_end_hashes) ;
210+ Ok ( ValidatedRawStr { n_hashes : n_start_safe } )
196211 }
197212 }
198213}
@@ -656,7 +671,7 @@ impl Cursor<'_> {
656671 false
657672 }
658673
659- /// Eats the double-quoted string an UnvalidatedRawStr
674+ /// Eats the double-quoted string and returns an ` UnvalidatedRawStr`.
660675 fn raw_double_quoted_string ( & mut self , prefix_len : usize ) -> UnvalidatedRawStr {
661676 debug_assert ! ( self . prev( ) == 'r' ) ;
662677 let mut valid_start: bool = false ;
0 commit comments