@@ -222,6 +222,57 @@ impl LineIndex {
222
222
}
223
223
224
224
/// Returns the [byte offset](TextSize) at `line` and `column`.
225
+ ///
226
+ /// ## Examples
227
+ ///
228
+ /// ### ASCII
229
+ ///
230
+ /// ```
231
+ /// use ruff_source_file::{LineIndex, OneIndexed};
232
+ /// use ruff_text_size::TextSize;
233
+ /// let source = r#"a = 4
234
+ /// c = "some string"
235
+ /// x = b"#;
236
+ ///
237
+ /// let index = LineIndex::from_source_text(source);
238
+ ///
239
+ /// // First line, first column
240
+ /// assert_eq!(index.offset(OneIndexed::from_zero_indexed(0), OneIndexed::from_zero_indexed(0), source), TextSize::new(0));
241
+ ///
242
+ /// // Second line, 4th column
243
+ /// assert_eq!(index.offset(OneIndexed::from_zero_indexed(1), OneIndexed::from_zero_indexed(4), source), TextSize::new(10));
244
+ ///
245
+ /// // Offset past the end of the first line
246
+ /// assert_eq!(index.offset(OneIndexed::from_zero_indexed(0), OneIndexed::from_zero_indexed(10), source), TextSize::new(6));
247
+ ///
248
+ /// // Offset past the end of the file
249
+ /// assert_eq!(index.offset(OneIndexed::from_zero_indexed(3), OneIndexed::from_zero_indexed(0), source), TextSize::new(29));
250
+ /// ```
251
+ ///
252
+ /// ### UTF8
253
+ ///
254
+ /// ```
255
+ /// use ruff_source_file::{LineIndex, OneIndexed};
256
+ /// use ruff_text_size::TextSize;
257
+ /// let source = r#"a = 4
258
+ /// c = "❤️"
259
+ /// x = b"#;
260
+ ///
261
+ /// let index = LineIndex::from_source_text(source);
262
+ ///
263
+ /// // First line, first column
264
+ /// assert_eq!(index.offset(OneIndexed::from_zero_indexed(0), OneIndexed::from_zero_indexed(0), source), TextSize::new(0));
265
+ ///
266
+ /// // Third line, 2nd column, after emoji
267
+ /// assert_eq!(index.offset(OneIndexed::from_zero_indexed(2), OneIndexed::from_zero_indexed(1), source), TextSize::new(20));
268
+ ///
269
+ /// // Offset past the end of the second line
270
+ /// assert_eq!(index.offset(OneIndexed::from_zero_indexed(1), OneIndexed::from_zero_indexed(10), source), TextSize::new(19));
271
+ ///
272
+ /// // Offset past the end of the file
273
+ /// assert_eq!(index.offset(OneIndexed::from_zero_indexed(3), OneIndexed::from_zero_indexed(0), source), TextSize::new(24));
274
+ /// ```
275
+ ///
225
276
pub fn offset ( & self , line : OneIndexed , column : OneIndexed , contents : & str ) -> TextSize {
226
277
// If start-of-line position after last line
227
278
if line. to_zero_indexed ( ) > self . line_starts ( ) . len ( ) {
@@ -233,15 +284,15 @@ impl LineIndex {
233
284
match self . kind ( ) {
234
285
IndexKind :: Ascii => {
235
286
line_range. start ( )
236
- + TextSize :: try_from ( column. get ( ) )
287
+ + TextSize :: try_from ( column. to_zero_indexed ( ) )
237
288
. unwrap_or ( line_range. len ( ) )
238
289
. clamp ( TextSize :: new ( 0 ) , line_range. len ( ) )
239
290
}
240
291
IndexKind :: Utf8 => {
241
292
let rest = & contents[ line_range] ;
242
293
let column_offset: TextSize = rest
243
294
. chars ( )
244
- . take ( column. get ( ) )
295
+ . take ( column. to_zero_indexed ( ) )
245
296
. map ( ruff_text_size:: TextLen :: text_len)
246
297
. sum ( ) ;
247
298
line_range. start ( ) + column_offset
0 commit comments