@@ -14,7 +14,7 @@ pub mod printf {
1414 /// Represents a single `printf`-style substitution.
1515 #[ derive( Clone , PartialEq , Debug ) ]
1616 pub enum Substitution < ' a > {
17- /// A formatted output substitution.
17+ /// A formatted output substitution with its internal byte offset .
1818 Format ( Format < ' a > ) ,
1919 /// A literal `%%` escape.
2020 Escape ,
@@ -28,6 +28,23 @@ pub mod printf {
2828 }
2929 }
3030
31+ pub fn position ( & self ) -> Option < ( usize , usize ) > {
32+ match * self {
33+ Substitution :: Format ( ref fmt) => Some ( fmt. position ) ,
34+ _ => None ,
35+ }
36+ }
37+
38+ pub fn set_position ( & mut self , start : usize , end : usize ) {
39+ match self {
40+ Substitution :: Format ( ref mut fmt) => {
41+ fmt. position = ( start, end) ;
42+ }
43+ _ => { }
44+ }
45+ }
46+
47+
3148 /// Translate this substitution into an equivalent Rust formatting directive.
3249 ///
3350 /// This ignores cases where the substitution does not have an exact equivalent, or where
@@ -57,6 +74,8 @@ pub mod printf {
5774 pub length : Option < & ' a str > ,
5875 /// Type of parameter being converted.
5976 pub type_ : & ' a str ,
77+ /// Byte offset for the start and end of this formatting directive.
78+ pub position : ( usize , usize ) ,
6079 }
6180
6281 impl < ' a > Format < ' a > {
@@ -257,19 +276,28 @@ pub mod printf {
257276 pub fn iter_subs ( s : & str ) -> Substitutions {
258277 Substitutions {
259278 s,
279+ pos : 0 ,
260280 }
261281 }
262282
263283 /// Iterator over substitutions in a string.
264284 pub struct Substitutions < ' a > {
265285 s : & ' a str ,
286+ pos : usize ,
266287 }
267288
268289 impl < ' a > Iterator for Substitutions < ' a > {
269290 type Item = Substitution < ' a > ;
270291 fn next ( & mut self ) -> Option < Self :: Item > {
271- let ( sub, tail) = parse_next_substitution ( self . s ) ?;
292+ let ( mut sub, tail) = parse_next_substitution ( self . s ) ?;
272293 self . s = tail;
294+ match sub {
295+ Substitution :: Format ( _) => if let Some ( ( start, end) ) = sub. position ( ) {
296+ sub. set_position ( start + self . pos , end + self . pos ) ;
297+ self . pos += end;
298+ }
299+ Substitution :: Escape => self . pos += 2 ,
300+ }
273301 Some ( sub)
274302 }
275303
@@ -301,7 +329,9 @@ pub mod printf {
301329 _ => { /* fall-through */ } ,
302330 }
303331
304- Cur :: new_at_start ( & s[ start..] )
332+ //let _ = Cur::new_at_start_with_pos(&s[..], start);
333+ //Cur::new_at_start(&s[start..])
334+ Cur :: new_at_start_with_pos ( & s[ ..] , start)
305335 } ;
306336
307337 // This is meant to be a translation of the following regex:
@@ -355,6 +385,7 @@ pub mod printf {
355385 precision : None ,
356386 length : None ,
357387 type_ : at. slice_between ( next) . unwrap ( ) ,
388+ position : ( start. at , next. at ) ,
358389 } ) ,
359390 next. slice_after ( )
360391 ) ) ;
@@ -541,6 +572,7 @@ pub mod printf {
541572 drop ( next) ;
542573
543574 end = at;
575+ let position = ( start. at , end. at ) ;
544576
545577 let f = Format {
546578 span : start. slice_between ( end) . unwrap ( ) ,
@@ -550,6 +582,7 @@ pub mod printf {
550582 precision,
551583 length,
552584 type_,
585+ position,
553586 } ;
554587 Some ( ( Substitution :: Format ( f) , end. slice_after ( ) ) )
555588 }
@@ -755,6 +788,12 @@ pub mod shell {
755788 }
756789 }
757790
791+ pub fn position ( & self ) -> Option < ( usize , usize ) > {
792+ match * self {
793+ _ => None ,
794+ }
795+ }
796+
758797 pub fn translate ( & self ) -> Option < String > {
759798 match * self {
760799 Substitution :: Ordinal ( n) => Some ( format ! ( "{{{}}}" , n) ) ,
@@ -918,7 +957,7 @@ mod strcursor {
918957
919958 pub struct StrCursor < ' a > {
920959 s : & ' a str ,
921- at : usize ,
960+ pub at : usize ,
922961 }
923962
924963 impl < ' a > StrCursor < ' a > {
@@ -929,6 +968,13 @@ mod strcursor {
929968 }
930969 }
931970
971+ pub fn new_at_start_with_pos ( s : & ' a str , at : usize ) -> StrCursor < ' a > {
972+ StrCursor {
973+ s,
974+ at,
975+ }
976+ }
977+
932978 pub fn at_next_cp ( mut self ) -> Option < StrCursor < ' a > > {
933979 match self . try_seek_right_cp ( ) {
934980 true => Some ( self ) ,
0 commit comments