~/bend-docscommunity

air/text.bend checks

raw source on the hub · import 0x1efee7e6292e6267db2ca5c7e267456a/air/text.bend as Text

1 import
import Base

Types

type Take source · line 192 · raw

Data

The first n bytes of a string and what follows them. TakeNeed asks for more input; TakeBad means byte n falls inside a character.

type Utf8 source · line 225 · raw

Data

Percent-decoding ----------------

%XX escapes are bytes, and a non-ASCII character arrives as two to four of them, so the decoder assembles UTF-8 as it goes. A multi-byte sequence in progress is Open; anything but its next continuation byte is an error.

type Decoding source · line 231 · raw

Data

The decoder's state between characters: the output so far, reversed, and the UTF-8 sequence in progress. Bad is sticky.

Definitions

def Two source · line 11 · raw

Data

A reusable pair of strings; String & String is the affine pair.

def fst source · line 14 · raw

@kv:Two -> String

def snd source · line 18 · raw

@kv:Two -> String

def rev_onto source · line 23 · raw

@xs:String -> @acc:String -> String

Prepends xs reversed onto acc. Tail-recursive, unlike String.append.

def append source · line 32 · raw

@a:String -> @b:String -> String

a ++ b without a stack frame per character of a: use it when a may be large, such as a request buffer.

def non_empty source · line 35 · raw

@s:String -> Bool

def head_is source · line 38 · raw

@s:String -> @+c:Char -> Bool

def split_once source · line 47 · raw

@s:String -> @+sep:Char -> @acc:String -> @hit:Bool -> Two

Splits at the first sep. hit says whether s starts with sep. Without a sep, the whole string is the first half.

def split_at source · line 56 · raw

@+s:String -> @+sep:Char -> Two

def split_seq source · line 60 · raw

@s:String -> @+sep:String -> @acc:String -> @hit:Bool -> Maybe<&2, Two>

Splits at the first occurrence of the substring sep, if any.

def split_str source · line 69 · raw

@+s:String -> @+sep:String -> Maybe<&2, Two>

def split_all.go source · line 74 · raw

@s:String -> @+sep:Char -> @line:String -> @acc:List<&2, String> -> @hit:Bool -> List<&2, String>

Splits on every sep. Tail-recursive, unlike String.split, so it is safe on a request head. hit says whether s starts with sep.

def split_all source · line 83 · raw

@+s:String -> @+sep:Char -> List<&2, String>

def push_non_empty source · line 86 · raw

@acc:List<&2, String> -> @+seg:String -> List<&2, String>

def segments.go source · line 94 · raw

@s:String -> @line:String -> @acc:List<&2, String> -> @hit:Bool -> List<&2, String>

The non-empty segments of a path: "/users//42/" gives ["users", "42"].

def segments source · line 103 · raw

@+path:String -> List<&2, String>

def map_get.fin source · line 106 · raw

@r:Pair(Map<&2, String>, String) -> String

def map_get source · line 110 · raw

@m:Map<&2, String> -> @key:String -> @d:String -> String

def count source · line 113 · raw

@xs:List<&2, String> -> @+acc:U32 -> U32

def drop_crlf source · line 121 · raw

@+s:String -> String

Drops the empty lines a client may send between requests.

def has_token.go source · line 129 · raw

@parts:List<&2, String> -> @+tok:String -> @found:Bool -> Bool

Whether v, a comma-separated header value, lists the token tok.

def has_token source · line 138 · raw

@v:String -> @+tok:String -> Bool

def digits.go source · line 143 · raw

@s:String -> @+acc:U32 -> @ok:Bool -> Maybe<&2, U32>

A strict decimal: digits only, no sign, no overflow. U32.read is looser than that, and a Content-Length must not be.

def digits source · line 155 · raw

@+s:String -> Maybe<&2, U32>

def hex_val source · line 159 · raw

@+x:U32 -> U32

The value of a hex digit, or 16 when it is not one.

def hex.go source · line 164 · raw

@s:String -> @+acc:U32 -> @ok:Bool -> Maybe<&2, U32>

def hex source · line 174 · raw

@+s:String -> Maybe<&2, U32>

def char_bytes source · line 178 · raw

@+x:U32 -> U32

UTF-8 byte count, which is what Content-Length counts.

def byte_length source · line 183 · raw

@s:String -> @acc:U32 -> U32

def take_bytes.go source · line 197 · raw

@t:String -> @done:Bool -> @fits:Bool -> @h:Char -> @+n:U32 -> @+b:U32 -> @acc:String -> Take

def take_bytes source · line 210 · raw

@s:String -> @+n:U32 -> Take

def on_char source · line 235 · raw

@acc:String -> @st:Utf8 -> @c:Char -> Decoding

def lead.pick source · line 245 · raw

@acc:String -> @+b:U32 -> @ok:Bool -> @ascii:Bool -> @two:Bool -> @three:Bool -> @four:Bool -> Decoding

A lead byte opens a sequence sized by its high bits; an ASCII byte is pushed as is. NUL, a stray continuation byte and the leads UTF-8 never uses (C0, C1, F5 and up) are refused.

def lead source · line 260 · raw

@acc:String -> @+b:U32 -> @ok:Bool -> Decoding

def cont.pick source · line 269 · raw

@acc:String -> @+need:U32 -> @+cp:U32 -> @+floor:U32 -> @valid:Bool -> @last:Bool -> @good:Bool -> Decoding

A continuation byte adds six bits. The last one closes the sequence, unless the code point is overlong, a surrogate, or past U+10FFFF.

def cont source · line 280 · raw

@acc:String -> @+need:U32 -> @+cp:U32 -> @+floor:U32 -> @+b:U32 -> @ok:Bool -> Decoding

def on_byte source · line 289 · raw

@acc:String -> @st:Utf8 -> @+b:U32 -> @ok:Bool -> Decoding

def escape source · line 297 · raw

@acc:String -> @st:Utf8 -> @+h1:U32 -> @+h2:U32 -> Decoding

One escaped byte, given as its two hex digits (16 when not a digit).

def percent_decode.go source · line 300 · raw

@s:String -> @+plus:Bool -> @d:Decoding -> Maybe<&2, String>

def needs_decode source · line 319 · raw

@s:String -> @+plus:Bool -> Bool

Whether s has a character that decoding would change: '%', or '+' when plus. A scan without allocation, so a plain segment is cheap.

def percent_decode.pick source · line 330 · raw

@+s:String -> @+plus:Bool -> @needed:Bool -> Maybe<&2, String>

def percent_decode source · line 340 · raw

@+s:String -> @+plus:Bool -> Maybe<&2, String>

Decodes %XX escapes into UTF-8 code points; plus turns '+' into a space, as query strings want. None on a bad or truncated escape, an escaped NUL, or an invalid, overlong or surrogate UTF-8 sequence.

def last_is.go source · line 345 · raw

@s:String -> @+c:Char -> @prev:Bool -> Bool

Whether the last character is c. Tail-recursive and allocation-free, unlike String.ends_with, which reverses the string.

def last_is source · line 352 · raw

@s:String -> @+c:Char -> Bool