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.
Took@head:String -> @rest:String -> Take
TakeNeedTake
TakeBadTake
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.
ClosedUtf8
Open@need:U32 -> @cp:U32 -> @floor:U32 -> Utf8
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.
BadDecoding
Next@acc:String -> @utf8:Utf8 -> Decoding
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