Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source pure

Package rle implements run-length encoding as a pure, reusable package: runs of a repeated byte collapse to a count a...

Readme View source

gno.land/p/moul/x/daily/rle/v0

Run-length encodingEncode, 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.

Overview

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).

Constants 1

const MaxLen

1const MaxLen = 4096
source

MaxLen bounds input so encode/decode gas stays predictable.

Variables 1

var ErrTooLong, ErrDigit, ErrMalformed

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)
source

Functions 3

func Decode

1func Decode(s string) (string, error)
source

Decode expands <count><char> pairs back into the original string.

func Encode

1func Encode(s string) (string, error)
source

Encode collapses runs of repeated bytes into <count><char> pairs.

func Ratio

1func Ratio(original, encoded string) int
source

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.

Imports 3

  • errors stdlib
  • strconv stdlib
  • strings stdlib

Source Files 3