Skip to main content

Query

Struct Query 

Source
pub struct Query<'index> { /* private fields */ }
Expand description

Query line and offset information.

NOTE: Since the Query can be sliced, we carefully store an extra beginning offset to trace slice beginning:

self.slice: [line0, line1, ..., EOF]

One should keep in mind that all line numbers passed into query methods should be numbers from the original Index and the slice is non-empty.

Implementations§

Source§

impl<'index> Query<'index>

Source

pub fn range(&self, range: Range<usize>) -> Self

Returns a zero-copy view over a subrange of lines.

The input range is interpreted over the logical line indices, i.e. 0..self.count(), where count() = self.slice.len() - 1.

Internally, self.slice stores a sentinel EOF offset as the last element: [line0, line1, ..., EOF].

To preserve this invariant, the returned slice includes one extra element at the end (the sentinel), so the actual slice is:

slice[range.start .. range.end + 1]

This ensures that every line i in the resulting view satisfies:

line i = [slice[i], slice[i+1])
§Panics

Panics if:

  • range.start > range.end
  • range.end > self.count()

These conditions indicate a violation of the API contract.

§Performance

This operation is zero-copy and does not allocate.

Invariant:

  • self.slice.len() >= 1
  • last element is EOF
  • valid line indices: 0..self.slice.len()-1
Source

pub fn range_from(&self, range_from: RangeFrom<usize>) -> Self

Returns a zero-copy view over lines starting from range_from.start to the end.

The input is interpreted over the logical line indices, i.e. 0..self.count().

Internally, self.slice always ends with a sentinel EOF offset: [line0, line1, ..., EOF].

Therefore, slicing with slice[start..] naturally preserves the sentinel, and no additional adjustment is needed.

The resulting view satisfies:

line i = [slice[i], slice[i+1])
§Panics

Panics if:

  • range_from.start > self.count()
§Edge Cases
  • If range_from.start == self.count(), the returned slice contains only the EOF sentinel. This represents an empty range of lines.
§Performance

This operation is zero-copy and does not allocate.

invariant: self.slice always ends with EOF so slice[start..] always contains a valid sentinel

Source

pub fn count(&self) -> usize

Count the total lines

Source§

impl Query<'_>

Source

pub fn line_offset(&self, line_no: usize) -> Option<Offset>

Given the number of line line_no, returns its start offset.

Source

pub fn line_span(&self, line_no: usize) -> Option<Range<Offset>>

Given the number of line line_no, Returns the byte range of the given line.

The returned range is half-open: [start, end), where start is the beginning of the line and end is the beginning of the next line (or EOF for the last line).

§Returns
  • Some(range) if the line exists.
  • None if the line index is out of bounds.
§Invariants
  • The internal index always contains a sentinel EOF offset, so line_offset(line_no + 1) is valid for the last line.
§Notes
  • The range is expressed in byte offsets, not character indices.
Source

pub fn beginning(&self) -> Option<Offset>

The beginning of the whole query range

Source

pub fn ending(&self) -> Option<Offset>

The ending of the whole query range

Source

pub fn contains(&self, offset: Offset) -> bool

check if contains the given offset

Source

pub fn locate_line(&self, offset: Offset) -> Option<usize>

Locate the line index for a given byte offset.

This method performs a binary search over the internal line index to find the line whose span contains the given offset.

§Returns
  • Some(line) if the offset lies within a known line.
  • None if:
    • the offset is before the beginning of the first line, or
    • the offset is at or beyond the sentinel EOF offset.
§Invariants
  • self.slice is a sorted list of line starting offsets.
  • The last element of self.slice is a sentinel EOF offset.
  • Each line i corresponds to the half-open interval: [slice[i], slice[i + 1]).
§Notes
  • The returned line index is zero-based.
  • If offset == EOF, this method returns None, since EOF is not considered part of any line.
Source

pub fn locate(&self, offset: Offset) -> Option<ZeroBased>

Locate the (line, column) position for a given byte offset.

This method uses the existing line index without performing any I/O. It resolves the line containing the offset, then computes the column as the byte distance from the beginning of that line.

§Returns
  • Some(ZeroBased(line, column)) if the offset lies within a known range.
  • None if the offset is out of bounds or beyond the indexed data.
§Invariants
  • The internal index contains valid starting offsets for all indexed lines.
  • Therefore, line_offset(line) is guaranteed to succeed for any line returned by locate_line.
§Notes
  • Both line and column are zero-based.
  • Column is measured in bytes, not characters.
  • This method does not attempt to extend the index; for streaming input, use the mutable variant instead.
Source

pub fn encode(&self, location: ZeroBased) -> Option<Offset>

Encode a (line, column) location into a byte Offset.

This method uses the existing line index without performing any I/O. It validates that the resulting offset lies within the bounds of the line.

§Returns
  • Some(offset) if the position is valid.
  • None if:
    • the line does not exist, or
    • the column is out of bounds.
§Invariants
  • line_span(line) returns a half-open range [start, end).
§Notes
  • Column is interpreted as a byte offset relative to the start of the line.
  • No UTF-8 character boundary checks are performed.

Trait Implementations§

Source§

impl<'index> Debug for Query<'index>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'index> Freeze for Query<'index>

§

impl<'index> RefUnwindSafe for Query<'index>

§

impl<'index> Send for Query<'index>

§

impl<'index> Sync for Query<'index>

§

impl<'index> Unpin for Query<'index>

§

impl<'index> UnsafeUnpin for Query<'index>

§

impl<'index> UnwindSafe for Query<'index>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.