Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Text

std/text is Flint’s portable text package.

It complements the built-in string and char types:

  • string handles read-only and view-returning text operations
  • char exposes Unicode scalar values plus small UTF-8 helpers
  • std/text provides split results and fixed-capacity mutable text through text.Buffer[N]

See String and Char for the built-in type surface.

Read-Only Text Surface

Most day-to-day string work reads naturally as methods on string:

let text = " key?=value\r\n"

let trimmed = text.trim()
let found = text.contains("?=")
let first = text.find("?=")
let split = text.split_once("?=")

Those methods are backed by the portable std/text layer and the minimal built-in string substrate. The important rule is that they remain allocation-free in the portable baseline.

text.Split

split_once and split_once_last return text.Split, a small allocation-free view result:

let text = "key?=value?=tail"
let split = text.split_once("?=")

if split.found() {
    let key = split.before()
    let value = split.after()
}

Current methods:

  • found()
  • before()
  • after()

If no delimiter matches, before() returns the full input and after() returns an empty string.

text.Buffer[N]

text.Buffer[N] is the current mutable text type for portable code.

It uses explicit fixed capacity and preserves UTF-8 validity instead of hiding allocation behind string methods.

use std/text as text

alias NameBuffer = text.Buffer[32]

fn build_name() -> Result<NameBuffer, text.BufferError> {
    let mut buffer = text.buffer(32)
    buffer.push_str("pico")?
    buffer.push('-')?
    buffer.push_str("uart")?
    return Ok(buffer)
}

The constructor:

let mut buffer = text.buffer(32)

creates an empty text.Buffer[32].

Core Buffer Methods

Current shipped core methods:

  • capacity()
  • len_bytes()
  • is_empty()
  • clear()
  • as_string()

Example:

let mut buffer = text.buffer(16)

let cap = buffer.capacity()
let empty = buffer.is_empty()

let pushed = buffer.push_str("hi")
let view = buffer.as_string()

buffer.clear()

as_string() returns an immutable string view over the live buffer contents.

Mutation Methods

Current shipped mutation methods:

  • push(ch: char) -> Result<(), text.BufferError>
  • push_ascii(byte: u8) -> Result<(), text.BufferError>
  • push_str(text: string) -> Result<(), text.BufferError>
  • insert(index: usize, text: string) -> Result<(), text.BufferError>
  • remove(index: usize) -> Result<char, text.BufferError>
  • replace(old: string, new: string) -> Result<u32, text.BufferError>

Example:

fn rewrite_name() -> Result<u32, text.BufferError> {
    let mut buffer = text.buffer(32)
    buffer.push_str("pico-led")?
    buffer.insert(4, "-board")?
    let removed = buffer.remove(4)?
    let replaced = buffer.replace("led", "uart")?
    return Ok(replaced)
}

Notes:

  • push, push_ascii, push_str, insert, and replace preserve UTF-8 validity
  • push_ascii(byte) is the explicit ASCII bridge for raw byte-stream input such as UART terminal bytes
  • remove(index) removes one UTF-8 scalar value at a validated byte boundary and returns that char
  • replace(old, new) returns the number of non-overlapping replacements
  • replace(old, new) rejects an empty pattern

text.BufferError

Current shipped error cases:

  • Full
  • InvalidIndex
  • EmptyPattern
  • NonAscii

These cover the current fixed-capacity and index-validation failure modes.

Current Backend Status

The current executable backend supports:

  • local text.Buffer[N] construction and mutation
  • local copies
  • direct by-value text.Buffer[N] parameters and returns

Current limitation:

  • by-value buffer arguments still need to come from local text.Buffer[N] bindings at the call site on the current backend

Design Direction

The portable text baseline is intentionally conservative:

  • UTF-8 everywhere
  • no hidden allocation for read-only string operations
  • fixed-capacity mutation through text.Buffer[N]
  • explicit ASCII naming for ASCII-only classification or future transforms

Future richer Unicode behavior belongs in a separate std/unicode layer rather than changing the meaning of the core text APIs across targets.