rokdocs
v0.1

rok::core::index

Indexing + slicing traits.

Spec 3.6: arr[i], arr[i,j], arr[1:3] all desugar through these traits. xs[i] / xs[i] = v on a struct or enum call index / index_set; fixed arrays and GcBuf<T> index directly (no call). a[i:j:k] calls a.slice(i..j) (then .step(k)), see collections::slice. Slices follow Python: bounds clamp to the length (never panic), a negative step reads them from the end.

Traits

Index

pub trait Index<I>
  • type Output
  • fn index(self, idx: I) -> Output

IndexSet

pub trait IndexSet<I>
  • type Value
  • fn index_set(self, idx: I, value: Value)

Sliceable

pub trait Sliceable<R>

a[i:j] (spec 2.3.4 names it Slice, which is also the view type of 2.9.7; one glob-imported name cannot be both).

  • type Output
  • fn slice(self, range: R) -> Output

Functions

spread_len

pub const fn spread_len(len: usize, want: usize)

Spec 3.6: the position of a signed index i in a length len - i itself, or len + i when negative (xs[-1] is the last). The compiler routes every signed position (xs[i] / a[i] on a List, Slice, fixed array; slice bounds of those and of str / StrBuf) through here; an unsigned one never is. A non-negative i is checked by the indexed type as before; a negative one past the start panics here. Spec 4.2.6: a List / Slice spread f(..xs) into fixed parameters needs exactly as many elements as it fills.

spread_names

pub const fn spread_names<V>(d: rok::core::collections::dict::Dict<str, V>, names: List<str>)

Spec 4.2.6: a Dict spread f(..d) is named arguments, so every key must name a parameter the spread may fill.

index_from_end

pub const fn index_from_end(i: isize, len: usize) -> usize

index_oob

pub const fn index_oob(what: str, i: usize, len: usize) -> !

Panics: {what} {i} out of bounds for length {len}. Out of line (a panic path is never inlined), so the checked accessors calling it stay small enough to inline.

clamp_range

pub const fn clamp_range(r: Range<usize>, n: usize) -> Range<usize>

r clamped to a length n the way Python clamps slice bounds: the end to n, the start to the end (a >= b is empty). Every Sliceable<Range<usize>> impl goes through here, so xs[5:100] and xs.slice(9..2) never panic.

slice_bound

pub const fn slice_bound(i: isize, len: usize) -> usize

A signed slice bound (xs[-3:], no step): len + i when negative, clamped at 0 (xs[-10:] is the whole list). The top is clamped by clamp_range.

slice_range

pub const fn slice_range(start: isize | none, stop: isize | none, step: isize, len: usize) -> Range<usize>

Python's slice(start, stop, step).indices(len) as the forward range r for which xs.slice(r).step(step) is xs[start:stop:step] (the compiler lowers every stepped slice of a List / Slice / array this way). A missing bound is none: 0 / len when step > 0, the last element / before the first when step < 0. A step of 0 panics.