@@ -725,6 +725,18 @@ impl fmt::Display for TokenWithSpan {
725725 }
726726}
727727
728+ pub struct TokenWithRange {
729+ pub token : Token ,
730+ pub start : usize ,
731+ pub end : usize ,
732+ }
733+
734+ impl TokenWithRange {
735+ pub fn new ( token : Token , start : usize , end : usize ) -> Self {
736+ Self { token, start, end }
737+ }
738+ }
739+
728740/// Tokenizer error
729741#[ derive( Debug , PartialEq , Eq ) ]
730742pub struct TokenizerError {
@@ -743,6 +755,7 @@ impl std::error::Error for TokenizerError {}
743755
744756struct State < ' a > {
745757 peekable : Peekable < Chars < ' a > > ,
758+ pub pos : usize ,
746759 pub line : u64 ,
747760 pub col : u64 ,
748761}
@@ -753,6 +766,7 @@ impl State<'_> {
753766 match self . peekable . next ( ) {
754767 None => None ,
755768 Some ( s) => {
769+ self . pos += 1 ;
756770 if s == '\n' {
757771 self . line += 1 ;
758772 self . col = 1 ;
@@ -878,6 +892,27 @@ impl<'a> Tokenizer<'a> {
878892 Ok ( twl. into_iter ( ) . map ( |t| t. token ) . collect ( ) )
879893 }
880894
895+ pub fn tokenize_with_range ( & mut self ) -> Result < Vec < TokenWithRange > , TokenizerError > {
896+ let mut tokens = Vec :: < TokenWithRange > :: new ( ) ;
897+ let mut state = State {
898+ peekable : self . query . chars ( ) . peekable ( ) ,
899+ line : 1 ,
900+ col : 1 ,
901+ pos : 0 ,
902+ } ;
903+
904+ let mut start = state. pos ;
905+ while let Some ( token) = self . next_token ( & mut state, tokens. last ( ) . map ( |t| & t. token ) ) ? {
906+ tokens. push ( TokenWithRange {
907+ token,
908+ start,
909+ end : state. pos ,
910+ } ) ;
911+ start = state. pos ;
912+ }
913+ Ok ( tokens)
914+ }
915+
881916 /// Tokenize the statement and produce a vector of tokens with location information
882917 pub fn tokenize_with_location ( & mut self ) -> Result < Vec < TokenWithSpan > , TokenizerError > {
883918 let mut tokens: Vec < TokenWithSpan > = vec ! [ ] ;
@@ -895,6 +930,7 @@ impl<'a> Tokenizer<'a> {
895930 peekable : self . query . chars ( ) . peekable ( ) ,
896931 line : 1 ,
897932 col : 1 ,
933+ pos : 0 ,
898934 } ;
899935
900936 let mut location = state. location ( ) ;
@@ -924,6 +960,7 @@ impl<'a> Tokenizer<'a> {
924960 peekable : word. chars ( ) . peekable ( ) ,
925961 line : 0 ,
926962 col : 0 ,
963+ pos : 0 ,
927964 } ;
928965 let mut s = peeking_take_while ( & mut inner_state, |ch| matches ! ( ch, '0' ..='9' | '.' ) ) ;
929966 let s2 = peeking_take_while ( chars, |ch| matches ! ( ch, '0' ..='9' | '.' ) ) ;
@@ -3509,6 +3546,7 @@ mod tests {
35093546 peekable : s. chars ( ) . peekable ( ) ,
35103547 line : 0 ,
35113548 col : 0 ,
3549+ pos : 0 ,
35123550 } ;
35133551
35143552 assert_eq ! (
0 commit comments