bend-kit-csv Releases (3): 0.3.0.0 0x5a0c8a3aeaac23c8e192c48890b1d961 indexed https://jend.leeeet.dev/files.txt?path=bend-kit-csv@0.3.0.0 0.2.0.0 0x3979161cdac065f4d7fc0e807196e138 unindexed https://jend.leeeet.dev/files.txt?path=bend-kit-csv@0.2.0.0 0.1.0.0 0xc44bda2e3431d17209e2df2adb8b59d8 unindexed https://jend.leeeet.dev/files.txt?path=bend-kit-csv@0.1.0.0 Definitions (34): Csv.Cur (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=Cur) # The unread bytes and the offset of the next record. type Cur is Type: Cur{src: Bytes.Bytes, at: U32} Csv.Next (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=Next) # One step of the cursor: a record and the cursor after it, the end of input, or # the offset of the first byte that breaks RFC 4180. type Next is Type: Row{fields: List<&1, Bytes.Bytes>, cur: Cur} End{} Bad{at: U32} Csv.Span (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=Span) # Reader # ------ # A field's bytes are src[s..e]. esc says the field was quoted and holds "". type Span is Data: Span{s: U32, e: U32, esc: Bool} Csv.Scan (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=Scan) # Spans are latest first. type Scan is Data: SRow{sp: List<&2, Span>, at: U32} SBad{at: U32} Csv.St (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=St) # Start: before a field. Unq: in an unquoted field. Q: in a quoted field. # QQ: just past a quote inside a quoted field. CR: just past a record's CR. type St is Data: SStart{} SUnq{} SQ{} SQQ{} SCR{} Csv.pk.if (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=pk.if) # Byte i, or 256 past the end. def pk.if(ok: Bool, a: Array, +i: U32) -> Array & U32: Csv.pk (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=pk) def pk(a: Array, +len: U32, +i: U32) -> Array & U32: Csv.start.sp (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=start.sp) # An empty line has no fields; a trailing comma adds an empty field. def start.sp(sp: List<&2, Span>, +i: U32) -> List<&2, Span>: Csv.rec.go (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=rec.go) # r holds byte i. s is where the open field starts. Every step but the last reads one byte. def rec.go(f: Nat, st: St, r: Array & U32, +len: U32, +i: U32, +s: U32, +esc: Bool, +sp: List<&2, Span>) -> Array & Scan: Csv.q (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=q) def q() -> Bytes.Bytes: Csv.qq (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=qq) def qq() -> Bytes.Bytes: Csv.unq.go (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=unq.go) # Pieces between "" pairs, latest first, with one quote between each. def unq.go(xs: List<&1, Bytes.Bytes>, acc: List<&1, Bytes.Bytes>) -> List<&1, Bytes.Bytes>: Csv.unq.of (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=unq.of) def unq.of(xs: List<&1, Bytes.Bytes>) -> Bytes.Bytes: Csv.field.of (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=field.of) # A quoted field's inner bytes with each "" as one quote. Quotes inside come in pairs. def field.of(esc: Bool, b: Bytes.Bytes) -> Bytes.Bytes: Csv.cut.fin (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=cut.fin) def cut.fin(+m: U32, +esc: Bool, r: Array & Array, acc: List<&1, Bytes.Bytes>) -> Array & List<&1, Bytes.Bytes>: Csv.cut.go (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=cut.go) # Spans latest first give fields in order. def cut.go(sp: List<&2, Span>, r: Array & List<&1, Bytes.Bytes>) -> Array & List<&1, Bytes.Bytes>: Csv.next.fin (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=next.fin) def next.fin(+len: U32, +at: U32, r: Array & List<&1, Bytes.Bytes>) -> Next: Csv.next.row (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=next.row) def next.row(+len: U32, r: Array & Scan) -> Next: Csv.next.if (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=next.if) def next.if(more: Bool, +len: U32, buf: Array, +at: U32) -> Next: Csv.cursor (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=cursor) # A cursor at the first record. def cursor(b: Bytes.Bytes) -> Cur: Csv.next (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=next) # The next record, End at the end of input, or Bad with the offset of the first bad byte. def next(c: Cur) -> Next: Csv.parse.go (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=parse.go) # Each record reads at least one byte, so len + 1 steps are enough. def parse.go(f: Nat, nx: Next, acc: List<&1, List<&1, Bytes.Bytes>>) -> Result<&1, &1, U32, List<&1, List<&1, Bytes.Bytes>>>: Csv.parse (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=parse) # Every record, or Fail with the offset of the first bad byte. def parse(b: Bytes.Bytes) -> Result<&1, &1, U32, List<&1, List<&1, Bytes.Bytes>>>: Csv.needs.go (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=needs.go) # Writer # ------ # Does a byte from i on need quotes? n counts the bytes left. def needs.go(n: Nat, r: Array & U32, +i: U32) -> Array & Bool: Csv.enc.rest (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=enc.rest) # The pieces after the first, each after "". def enc.rest(xs: List<&1, Bytes.Bytes>, acc: List<&1, Bytes.Bytes>) -> List<&1, Bytes.Bytes>: Csv.enc.parts (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=enc.parts) def enc.parts(xs: List<&1, Bytes.Bytes>, acc: List<&1, Bytes.Bytes>) -> List<&1, Bytes.Bytes>: Csv.enc.pick (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=enc.pick) def enc.pick(+len: U32, r: Array & Bool, acc: List<&1, Bytes.Bytes>) -> List<&1, Bytes.Bytes>: Csv.enc.field (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=enc.field) # Pieces are latest first. A field is quoted only when it holds a quote, comma, CR, or LF. def enc.field(f: Bytes.Bytes, acc: List<&1, Bytes.Bytes>) -> List<&1, Bytes.Bytes>: Csv.enc.more (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=enc.more) def enc.more(fs: List<&1, Bytes.Bytes>, acc: List<&1, Bytes.Bytes>) -> List<&1, Bytes.Bytes>: Csv.enc.only.if (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=enc.only.if) def enc.only.if(empty: Bool, f: Bytes.Bytes, acc: List<&1, Bytes.Bytes>) -> List<&1, Bytes.Bytes>: Csv.enc.only (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=enc.only) def enc.only(f: Bytes.Bytes, acc: List<&1, Bytes.Bytes>) -> List<&1, Bytes.Bytes>: Csv.enc.fields (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=enc.fields) def enc.fields(fs: List<&1, Bytes.Bytes>, acc: List<&1, Bytes.Bytes>) -> List<&1, Bytes.Bytes>: Csv.enc.recs (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=enc.recs) def enc.recs(rs: List<&1, List<&1, Bytes.Bytes>>, acc: List<&1, Bytes.Bytes>) -> List<&1, Bytes.Bytes>: Csv.encode (https://jend.leeeet.dev/definition.txt?path=bend-kit-csv@0.3.0.0/csv.bend&name=encode) # Records as RFC 4180 text: fields joined by commas, each record ended by CRLF. def encode(rs: List<&1, List<&1, Bytes.Bytes>>) -> Bytes.Bytes: