const MaxLen
MaxLen bounds input so encode/decode gas stays predictable.
Package rle implements run-length encoding as a pure, reusable package: runs of a repeated byte collapse to a count a...
gno.land/p/moul/x/daily/rle/v0Run-length encoding — Encode, Decode, Ratio, MaxLen.
Runs of a repeated byte collapse to <count><char>, counts in decimal:
"aaabbc" → "3a2b1c".
1import "gno.land/p/moul/x/daily/rle/v0"
2
3rle.Encode("aaabbc") // "3a2b1c", nil
4rle.Decode("3a2b1c") // "aaabbc", nil
5rle.Ratio("abcdef", "1a1b1c1d1e1f") // 200 — bigger than the input!
Every run carries a count, including runs of one. A uniform grammar is
cheaper to decode and impossible to get subtly wrong, at the cost of expanding
data that has no runs. That trade is deliberate and visible: Ratio returns
over 100 when the "compression" grew the data, because RLE only wins on runny
input and pretending otherwise would be dishonest.
Digits are rejected by Encode — in the output they would be
indistinguishable from a run count, so a round-trip would silently return the
wrong string. Better to refuse.
Decode bounds the expanded size too, not just its input: "999999x" is
seven bytes that would otherwise become a megabyte.
Live demo: r/moul/x/daily/rledemo
· render it at /r/moul/x/daily/rledemo/v0.
Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.
🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.
Package rle implements run-length encoding as a pure, reusable package: runs of a repeated byte collapse to a count and the byte.
The encoding is `<count><char>` with counts in decimal, e.g. "aaabbc" → "3a2b1c". Every run is emitted with its count, including runs of one — a uniform grammar is cheaper to decode and impossible to get subtly wrong, at the cost of expanding data that has no runs at all. RLE is a *win only on runny data*; Encode can legitimately produce output longer than its input, and the demo shows exactly that case rather than hiding it.
Digits cannot appear in the input, since they would be indistinguishable from a count on the way back; Encode rejects them rather than round-tripping wrong.
A live demo of this package is at r/moul/x/daily/rledemo(/r/moul/x/daily/rledemo/v0).
1var (
2 // ErrTooLong is returned when input exceeds MaxLen.
3 ErrTooLong = errors.New("rle: input too long")
4 // ErrDigit is returned when input contains a digit, which would be
5 // ambiguous with a run count.
6 ErrDigit = errors.New("rle: input must not contain digits")
7 // ErrMalformed is returned when decoding input that is not <count><char>.
8 ErrMalformed = errors.New("rle: malformed input")
9)Decode expands <count><char> pairs back into the original string.
Encode collapses runs of repeated bytes into <count><char> pairs.
Ratio returns len(encoded)/len(original) as a percentage, rounded down. Over 100 means the encoding made the data BIGGER, which is the honest outcome for input without runs.