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 humanize formats numbers for people rather than machines, as a pure, reusable package: byte sizes, thousands ...

Readme View source

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

Human-facing number formattingBytes, Comma, Ordinal, Plural, Blocks, Truncate.

1import "gno.land/p/moul/x/daily/humanize/v0"
2
3humanize.Bytes(1536)        // "1.5 KiB"
4humanize.Comma(1234567)     // "1,234,567"
5humanize.Ordinal(12)        // "12th"  — not "12nd"
6humanize.Plural(2, "mouse", "mice")  // "2 mice"
7humanize.Blocks(1234)       // "~1,200 blocks"
8humanize.Truncate("ééé", 2) // "é…"

Integer-only, on purpose. No floats anywhere: a rendered value that differed between nodes would be a consensus bug, so the single decimal place in Bytes comes from scaling by 10 and taking a remainder.

Durations are in blocks, never seconds. There is no wall clock on chain, so "about 2 hours" is a lie dressed as precision. Blocks says ~1,200 blocks and lets the caller decide what that means on their chain — and rounds deliberately, because false precision is worse than none.

Ordinal handles the teens (11th/12th/13th, not 11st/12nd/13rd) — the case naive implementations get wrong. Truncate counts runes, so multi-byte text is never sliced mid-character.

Live demo: r/moul/x/daily/humanizedemo · render it at /r/moul/x/daily/humanizedemo/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 humanize formats numbers for people rather than machines, as a pure, reusable package: byte sizes, thousands separators, ordinals, pluralisation and block-height "durations".

Everything is integer-only. There are no floats here on purpose: gno has no float determinism guarantees worth relying on for consensus output, and a rendered value that differs between nodes would be a consensus bug. One decimal place is produced by scaling by 10 and taking a remainder.

Durations are expressed in BLOCKS, not seconds. There is no wall clock on chain, so "about 2 hours" is a lie dressed as precision; this package says "~1200 blocks" and lets the caller decide what that means on their chain.

A live demo of this package is at r/moul/x/daily/humanizedemo(/r/moul/x/daily/humanizedemo/v0).

Functions 6

func Blocks

1func Blocks(n int64) string
source

Blocks renders a block count at a coarse magnitude — deliberately vague, because a block count is not a wall-clock duration.

func Bytes

1func Bytes(n int64) string
source

Bytes renders n bytes with SI-ish binary units and one decimal place. Negative input is rendered with a leading minus rather than rejected.

func Comma

1func Comma(n int64) string
source

Comma inserts thousands separators: 1234567 -> "1,234,567".

func Ordinal

1func Ordinal(n int64) string
source

Ordinal renders 1 -> "1st", 2 -> "2nd", 11 -> "11th".

The teens are the trap: 11/12/13 take "th" despite ending in 1/2/3, so the 11–13 case must be checked before the last digit.

func Plural

1func Plural(n int64, word, plural string) string
source

Plural returns "1 block" / "2 blocks", using plural when given, else word+"s".

func Truncate

1func Truncate(s string, max int) string
source

Truncate shortens s to at most max runes, appending "…" when it cut. Counts RUNES, not bytes, so a multi-byte string is not sliced mid-character.

Imports 2

  • strconv stdlib
  • strings stdlib

Source Files 3