An incremental byte buffer builder. Add chunks with .add, then finalize with .build.
Module Bytes
type Bytes = Bytes
type Bytes.Parser<e> = recursive iterative@attempt choice { .byte => either { .byte (Byte) self, .end Result<e, !>, }, .close => Result<e, !>, .match => [Bytes.Pattern, Bytes.Pattern] either { .end Result<e, !>, .fail self@attempt, .match (Bytes, Bytes) self, }, .matchEnd => [Bytes.Pattern, Bytes.Pattern] either { .end Result<e, !>, .fail self@attempt, .match (Bytes, Bytes)!, }, .remainder => Result<e, Bytes>, }
A streaming byte parser, parameterized by an error type e.
Works like String.Parser but operates on raw bytes.
Operations:
.close— close the parser..remainder— consume the parser and return all remaining bytes..byte— read the next byte. Returns.endor.byte(b)..match(prefix, suffix)— find the leftmost split whereprefixmatches the left part andsuffixmatches the longest possible right part. Returns.match(prefix_bytes, suffix_bytes)on success,.failif no match (parser position unchanged), or.endif input is empty..matchEnd(prefix, suffix)— like.match, but the suffix extends to the end of input. Terminates the parser on success.
Use .begin/.loop (from the recursive wrapper) to iterate over multiple matches.
type Bytes.Pattern = recursive either { .and List<self>, .bytes Bytes, .concat List<self>, .empty !, .max Nat, .min Nat, .non Byte.Class, .one Byte.Class, .or List<self>, .repeat self, .repeat1 self, }
A pattern for matching within byte sequences.
Atomic patterns:
.empty!— matches empty bytes..bytes b— matches literal bytes..one class— matches a single byte of the givenByte.Class..non class— matches a single byte NOT in the givenByte.Class..min n— matches at leastnbytes (any)..max n— matches at mostnbytes (any).
Combinators:
.repeat p— matches zero or more repetitions of patternp..repeat1 p— matches one or more repetitions of patternp..concat ps— matches a sequence of patterns in order..and ps— matches only if all patterns match the same input..or ps— matches if any of the patterns match.
type Bytes.Reader<e> = recursive choice { .close => Result<e, !>, .read => Result<e, either { .chunk (Bytes) self, .end !, }>, }
A streaming byte reader, parameterized by an error type e.
.close— close the reader and return any error..read— read the next chunk. Returns.endwhen exhausted, or.chunk(bytes)with the next chunk of data.
type Bytes.Writer<e> = iterative choice { .close => Result<e, !>, .flush => Result<e, self>, .write => [Bytes] Result<e, self>, }
A streaming byte writer, parameterized by an error type e.
.close— close the writer, flushing any pending data..flush— flush pending data without closing..write(bytes)— write a chunk of bytes.
dec Bytes.Builder : Bytes.Builder
Creates a new byte buffer Builder.
dec Bytes.EmptyReader : Bytes.Reader<either {}>
Creates a Reader that is immediately empty.
Returns the length of a byte sequence.
dec Bytes.Parser : [Bytes] Bytes.Parser<either {}>
Creates a byte Parser from a byte sequence.
The error type is either {} (impossible).
dec Bytes.ParserFromReader : <e>[Bytes.Reader<e>] Bytes.Parser<e>
Creates a byte Parser from a Reader.
The error type matches the reader's error type.
dec Bytes.PipeReader : [type e, [Bytes.Writer<!>] Result<e, !>] Bytes.Reader<e>
Creates a Reader from a function that writes to a Writer.
The function receives a Writer<!> whose writes fail with ! if the
reader's consumer closes early, signaling the writer to stop.
The function returns Result<e, !> to propagate errors to the reader.
Bytes.PipeReader(type MyError, [w]
catch ! => .ok! in
do {
w.write("hello").try
w.close.try
} in .ok!
)
dec Bytes.Reader : [Bytes] Bytes.Reader<either {}>
Creates a Reader from a byte sequence. The error type is either {} (impossible).