pub struct LineMap { /* private fields */ }Expand description
A precomputed table of line-start byte offsets for a single source file.
Constructed once per file via LineMap::new; the compiler and diagnostics
layer read it cheaply thereafter.
Implementations§
Source§impl LineMap
impl LineMap
Sourcepub fn new(text: &str) -> LineMap
pub fn new(text: &str) -> LineMap
Build a line map from source text. \n, \r\n, and \r all count as
line terminators, matching how the input parser treats logical lines.
Sourcepub fn offset_to_linecol(&self, offset: BytePos) -> LineCol
pub fn offset_to_linecol(&self, offset: BytePos) -> LineCol
Convert a byte offset to a 1-based (line, column).
Offsets past the end of the file clamp to the last byte of the last line rather than overflowing, so a slightly-out-of-range span still renders something sensible.
Sourcepub fn linecol_to_offset(&self, lc: LineCol) -> Option<BytePos>
pub fn linecol_to_offset(&self, lc: LineCol) -> Option<BytePos>
Convert a 1-based (line, column) back to a byte offset.
Returns None if line is zero or beyond the number of lines. A column
past the end of the line clamps to the line’s last byte.
Sourcepub fn line_count(&self) -> usize
pub fn line_count(&self) -> usize
The total number of lines.
Sourcepub fn line_range(&self, line: u32) -> Option<(BytePos, BytePos)>
pub fn line_range(&self, line: u32) -> Option<(BytePos, BytePos)>
The byte range [start, end) of a given 1-based line number, or None
if the line number is out of range.
end is the byte offset where the next line begins (or the file end for
the final line), so it includes any line terminator. Callers that render
the line text should trim it with LineMap::trim_line_terminator.
Sourcepub fn trim_line_terminator(
text: &[u8],
start: BytePos,
end: BytePos,
) -> BytePos
pub fn trim_line_terminator( text: &[u8], start: BytePos, end: BytePos, ) -> BytePos
The content end of a line extent [start, end): end minus the bytes of
the single line terminator (\n, \r, or \r\n) that separates this
line from the next. Reads the actual bytes, so a CRLF is trimmed as one
terminator and not as two.
LineMap::line_range deliberately hands back the extent including
the terminator and tells the caller to trim it — this is that trim, and
the only copy of it. The terminator set has to stay in step with the
scanner in LineMap::new, so the rule lives beside the scanner: a
change there is one edit rather than several that can silently desync.
Takes the bytes rather than reading self.text so that a caller which
already holds the source trims against the very bytes it is about to
slice. An extent with nothing in it, and a final line with no terminator
at all, are both returned unchanged.