url/views

String views This provides zero-cost string reading along with some primitives like suffix deletion.

It also acts as a stateful buffer optionally, meaning it can hold certain flags that are used to avoid conversions to strings (like convert-all-to-lower/upper)

NOTE: A view does not own the data it is pointing to. It is the programmer's job to ensure that the underlying data address is not deallocated. If it is, any subsequent operations on the view will result in undefined behaviour.

Copyright (C) 2026 Trayambak Rai (xtrayambak@disroot.org)

Types

StringView = object
  data*: ptr char
StringViewFlag {.pure, size: 1.} = enum
  Heterogenous = 0, AllLower = 1

View flags are an optimization to prevent conversions to strings when possible. For example, if you wanted to turn a view into lowercase normally, you'd have to do: .. code-block:: nim toStringView(strutils.toLowerAscii($view))

Which involves a string copy, which is expensive and bad. Flags let the programmer signal how a view's content may be mutated, in a zero-copy manner.

Procs

func `$`(view: StringView): string {....raises: [], tags: [], forbids: [].}
NOTE: This routine creates a copy of the underlying buffer.
proc `=copy`(dest: var StringView; source: StringView) {....raises: [], tags: [],
    forbids: [].}
proc `=destroy`(view: StringView) {....raises: [], tags: [], forbids: [].}
func anyOf(view: StringView;
           filter: proc (b: char): bool {.noSideEffect, inline.}): bool {.
    inline, ...raises: [Exception], tags: [RootEffect], forbids: [].}
func slice(view: StringView; start: uint32; stop: uint32): StringView {.
    ...raises: [], tags: [], forbids: [].}
func toStringView(data: ptr char; size: uint32): StringView {.inline,
    ...raises: [], tags: [], forbids: [].}
func toStringView(str: string): StringView {.inline, ...raises: [], tags: [],
    forbids: [].}

Iterators

iterator items(view: StringView): char {....raises: [], tags: [], forbids: [].}
iterator pairs(view: StringView): tuple[i: int, v: char] {....raises: [], tags: [],
    forbids: [].}

Templates

template `==`(a, b: StringView): bool
template `==`(a: StringView; b: string): bool
template `[]`(view: StringView; i: uint32): char
NOTE: This does not apply flags.
template beyond(view: StringView; offset: uint32): StringView
template endsWith(view: StringView; c: char): bool
template len(view: StringView): uint32
template processed(view: StringView; c: char): char
template removePrefix(view: var StringView; i: uint32)
template removeSuffix(view: var StringView; i: uint32)