11use std:: collections:: HashMap ;
22
3+ use lsp_types:: Position ;
4+
35/// A struct which contains information about line numbers of a source file,
46/// and can convert between byte offsets that are used in the compiler and
57/// line-column pairs used in LSP.
@@ -107,10 +109,10 @@ impl LineNumbers {
107109 }
108110 }
109111
110- /// Returns the byte index of the corresponding 1-indexed line and column
111- /// numbers, translating from a UTF-16 character index to a UTF-8 byte index.
112- pub fn byte_index ( & self , line : u32 , character : u32 ) -> u32 {
113- let line_start = match self . line_starts . get ( line as usize - 1 ) {
112+ /// Returns the byte index of the corresponding LSP line- column `Position`,
113+ /// translating from a UTF-16 character index to a UTF-8 byte index.
114+ pub fn byte_index ( & self , position : Position ) -> u32 {
115+ let line_start = match self . line_starts . get ( position . line as usize ) {
114116 Some ( & line_start) => line_start,
115117 None => return self . length ,
116118 } ;
@@ -119,7 +121,7 @@ impl LineNumbers {
119121 let mut u16_offset = 0 ;
120122
121123 loop {
122- if u16_offset >= character - 1 {
124+ if u16_offset >= position . character {
123125 break ;
124126 }
125127
@@ -146,10 +148,34 @@ pub fn main() {
146148"# ;
147149 let line_numbers = LineNumbers :: new ( src) ;
148150
149- assert_eq ! ( line_numbers. byte_index( 1 , 1 ) , 0 ) ;
150- assert_eq ! ( line_numbers. byte_index( 1 , 5 ) , 4 ) ;
151- assert_eq ! ( line_numbers. byte_index( 100 , 1 ) , src. len( ) as u32 ) ;
152- assert_eq ! ( line_numbers. byte_index( 3 , 2 ) , 18 ) ;
151+ assert_eq ! (
152+ line_numbers. byte_index( Position {
153+ line: 0 ,
154+ character: 0
155+ } ) ,
156+ 0
157+ ) ;
158+ assert_eq ! (
159+ line_numbers. byte_index( Position {
160+ line: 0 ,
161+ character: 4
162+ } ) ,
163+ 4
164+ ) ;
165+ assert_eq ! (
166+ line_numbers. byte_index( Position {
167+ line: 100 ,
168+ character: 0
169+ } ) ,
170+ src. len( ) as u32
171+ ) ;
172+ assert_eq ! (
173+ line_numbers. byte_index( Position {
174+ line: 2 ,
175+ character: 1
176+ } ) ,
177+ 18
178+ ) ;
153179}
154180
155181// https://github.com/gleam-lang/gleam/issues/3628
@@ -165,10 +191,34 @@ pub fn main() {
165191"# ;
166192 let line_numbers = LineNumbers :: new ( src) ;
167193
168- assert_eq ! ( line_numbers. byte_index( 2 , 7 ) , 30 ) ;
169- assert_eq ! ( line_numbers. byte_index( 6 , 3 ) , 52 ) ;
170- assert_eq ! ( line_numbers. byte_index( 6 , 18 ) , 75 ) ;
171- assert_eq ! ( line_numbers. byte_index( 7 , 2 ) , 91 ) ;
194+ assert_eq ! (
195+ line_numbers. byte_index( Position {
196+ line: 1 ,
197+ character: 6
198+ } ) ,
199+ 30
200+ ) ;
201+ assert_eq ! (
202+ line_numbers. byte_index( Position {
203+ line: 5 ,
204+ character: 2
205+ } ) ,
206+ 52
207+ ) ;
208+ assert_eq ! (
209+ line_numbers. byte_index( Position {
210+ line: 5 ,
211+ character: 17
212+ } ) ,
213+ 75
214+ ) ;
215+ assert_eq ! (
216+ line_numbers. byte_index( Position {
217+ line: 6 ,
218+ character: 1
219+ } ) ,
220+ 91
221+ ) ;
172222}
173223
174224// https://github.com/gleam-lang/gleam/issues/3628
@@ -205,6 +255,7 @@ pub fn main() {
205255 ) ;
206256}
207257
258+ /// A 1-index line and column position
208259#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
209260pub struct LineColumn {
210261 pub line : u32 ,
0 commit comments