PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

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

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v1
Namespace
moul / x / daily / humanize
Files
4 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/moul/x/daily/humanize/v1
gno
0.9

Files (4)

  • README.mdmarkdown
  • gnomod.tomltoml
  • humanize.gnogno
  • humanize_test.gnogno
humanize.gnogno
1// Package humanize formats numbers for people rather than machines, as a pure,2// reusable package: byte sizes, thousands separators, ordinals, pluralisation3// and block-height "durations".4//5// Everything is integer-only. There are no floats here on purpose: gno has no6// float determinism guarantees worth relying on for consensus output, and a7// rendered value that differs between nodes would be a consensus bug. One8// decimal place is produced by scaling by 10 and taking a remainder.9//10// Durations are expressed in BLOCKS, not seconds. There is no wall clock on11// chain, so "about 2 hours" is a lie dressed as precision; this package says12// "~1200 blocks" and lets the caller decide what that means on their chain.13//14// A live demo of this package is at15// [r/moul/x/daily/humanizedemo](/r/moul/x/daily/humanizedemo/v0).16package humanize1718import (19	"strconv"20	"strings"21)2223// Bytes renders n bytes with SI-ish binary units and one decimal place.24// Negative input is rendered with a leading minus rather than rejected.25func Bytes(n int64) string {26	neg := n < 027	if neg {28		n = -n29	}30	const unit = 102431	if n < unit {32		s := strconv.FormatInt(n, 10) + " B"33		if neg {34			return "-" + s35		}36		return s37	}38	units := []string{"KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}39	div := int64(unit)40	i := 041	for n/div >= unit && i < len(units)-1 {42		div *= unit43		i++44	}45	// one decimal place without floats: scale by 10, then split46	scaled := n * 10 / div47	whole, freq := scaled/10, scaled%1048	s := strconv.FormatInt(whole, 10)49	if freq != 0 {50		s += "." + strconv.FormatInt(freq, 10)51	}52	s += " " + units[i]53	if neg {54		return "-" + s55	}56	return s57}5859// Comma inserts thousands separators: 1234567 -> "1,234,567".60func Comma(n int64) string {61	// The magnitude goes through uint64 rather than -n: -n on math.MinInt64 is62	// math.MinInt64 again, so FormatInt emits its own sign and the neg branch63	// below prepended a second one. v0 returned "--9,223,372,036,854,775,808".64	neg := n < 065	var m uint6466	if neg {67		m = uint64(-(n+1)) + 168	} else {69		m = uint64(n)70	}71	s := strconv.FormatUint(m, 10)72	var b strings.Builder73	for i, c := range []byte(s) {74		if i > 0 && (len(s)-i)%3 == 0 {75			b.WriteByte(',')76		}77		b.WriteByte(c)78	}79	if neg {80		return "-" + b.String()81	}82	return b.String()83}8485// Ordinal renders 1 -> "1st", 2 -> "2nd", 11 -> "11th".86//87// The teens are the trap: 11/12/13 take "th" despite ending in 1/2/3, so the88// 11–13 case must be checked before the last digit.89func Ordinal(n int64) string {90	s := strconv.FormatInt(n, 10)91	a := n92	if a < 0 {93		a = -a94	}95	if a%100 >= 11 && a%100 <= 13 {96		return s + "th"97	}98	switch a % 10 {99	case 1:100		return s + "st"101	case 2:102		return s + "nd"103	case 3:104		return s + "rd"105	}106	return s + "th"107}108109// Plural returns "1 block" / "2 blocks", using plural when given, else word+"s".110func Plural(n int64, word, plural string) string {111	if n == 1 || n == -1 {112		return strconv.FormatInt(n, 10) + " " + word113	}114	if plural == "" {115		plural = word + "s"116	}117	return strconv.FormatInt(n, 10) + " " + plural118}119120// Blocks renders a block count at a coarse magnitude — deliberately vague,121// because a block count is not a wall-clock duration.122func Blocks(n int64) string {123	switch {124	case n < 0:125		return "in the past"126	case n == 0:127		return "now"128	case n < 10:129		return Plural(n, "block", "")130	case n < 1000:131		return "~" + Comma(n/10*10) + " blocks"132	default:133		return "~" + Comma(n/100*100) + " blocks"134	}135}136137// Truncate shortens s to at most max runes, appending "…" when it cut.138// Counts RUNES, not bytes, so a multi-byte string is not sliced mid-character.139func Truncate(s string, max int) string {140	if max <= 0 {141		return ""142	}143	r := []rune(s)144	if len(r) <= max {145		return s146	}147	if max == 1 {148		return "…"149	}150	return string(r[:max-1]) + "…"151}152

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.