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/nt/ufmt/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
nt / ufmt
Files
5 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/nt/ufmt/v0
gno
0.9

Files (5)

  • README.mdmarkdown
  • gnomod.tomltoml
  • doc.gnogno
  • ufmt.gnogno
  • ufmt_test.gnogno
ufmt.gnogno
1// Package ufmt provides utility functions for formatting strings, similarly to2// the Go package "fmt", of which only a subset is currently supported (hence3// the name µfmt - micro fmt). It includes functions like Printf, Sprintf,4// Fprintf, and Errorf.5// Supported formatting verbs are documented in the Sprintf function.6package ufmt78import (9	"errors"10	"io"11	"strconv"12	"strings"13	"unicode/utf8"14)1516// buffer accumulates formatted output as a byte slice.17type buffer []byte1819func (b *buffer) write(p []byte) {20	*b = append(*b, p...)21}2223func (b *buffer) writeString(s string) {24	*b = append(*b, s...)25}2627func (b *buffer) writeByte(c byte) {28	*b = append(*b, c)29}3031func (b *buffer) writeRune(r rune) {32	*b = utf8.AppendRune(*b, r)33}3435// printer holds state for formatting operations.36type printer struct {37	buf buffer38}3940func newPrinter() *printer {41	return &printer{}42}4344// Sprint formats using the default formats for its operands and returns the resulting string.45// Sprint writes the given arguments with spaces between arguments.46func Sprint(a ...any) string {47	p := newPrinter()48	p.doPrint(a)49	return string(p.buf)50}5152// doPrint formats arguments using default formats and writes to printer's buffer.53// Spaces are added between arguments.54func (p *printer) doPrint(args []any) {55	for argNum, arg := range args {56		if argNum > 0 {57			p.buf.writeRune(' ')58		}5960		switch v := arg.(type) {61		case string:62			p.buf.writeString(v)63		case (interface{ String() string }):64			p.buf.writeString(v.String())65		case error:66			p.buf.writeString(v.Error())67		case float64:68			p.buf.writeString(Sprintf("%f", v))69		case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:70			p.buf.writeString(Sprintf("%d", v))71		case bool:72			if v {73				p.buf.writeString("true")74			} else {75				p.buf.writeString("false")76			}77		case nil:78			p.buf.writeString("<nil>")79		default:80			p.buf.writeString("(unhandled)")81		}82	}83}8485// doPrintln appends a newline after formatting arguments with doPrint.86func (p *printer) doPrintln(a []any) {87	p.doPrint(a)88	p.buf.writeByte('\n')89}9091// Sprintf offers similar functionality to Go's fmt.Sprintf, or the sprintf92// equivalent available in many languages, including C/C++.93// The number of args passed must exactly match the arguments consumed by the format.94// A limited number of formatting verbs and features are currently supported.95//96// Supported verbs:97//98//	%s: Places a string value directly.99//	    If the value implements the interface interface{ String() string },100//	    the String() method is called to retrieve the value. Same about Error()101//	    string.102//	%c: Formats the character represented by Unicode code point103//	%d: Formats an integer value using package "strconv".104//	    Currently supports only uint, uint64, int, int64.105//	%f: Formats a float value, with a default precision of 6.106//	%e: Formats a float with scientific notation; 1.23456e+78107//	%E: Formats a float with scientific notation; 1.23456E+78108//	%F: The same as %f109//	%g: Formats a float value with %e for large exponents, and %f with full precision for smaller numbers110//	%G: Formats a float value with %G for large exponents, and %F with full precision for smaller numbers111//	%t: Formats a boolean value to "true" or "false".112//	%x: Formats an integer value as a hexadecimal string.113//	    Currently supports only uint8, []uint8, [32]uint8.114//	%c: Formats a rune value as a string.115//	    Currently supports only rune, int.116//	%q: Formats a string value as a quoted string.117//	%T: Formats the type of the value.118//	%v: Formats the value with a default representation appropriate for the value's type119//	    - nil: <nil>120//	    - bool: true/false121//	    - integers: base 10122//	    - float64: %g format123//	    - string: verbatim124//	    - types with String()/Error(): method result125//	    - others: (unhandled)126//	%%: Outputs a literal %. Does not consume an argument.127//128// Unsupported verbs or type mismatches produce error strings like "%!d(string=foo)".129func Sprintf(format string, a ...any) string {130	p := newPrinter()131	p.doPrintf(format, a)132	return string(p.buf)133}134135// doPrintf parses the format string and writes formatted arguments to the buffer.136func (p *printer) doPrintf(format string, args []any) {137	sTor := []rune(format)138	end := len(sTor)139	argNum := 0140	argLen := len(args)141142	for i := 0; i < end; {143		isLast := i == end-1144		c := sTor[i]145146		if isLast || c != '%' {147			// we don't check for invalid format like a one ending with "%"148			p.buf.writeRune(c)149			i++150			continue151		}152153		length := -1154		precision := -1155		i++ // skip '%'156157		digits := func() string {158			start := i159			for i < end && sTor[i] >= '0' && sTor[i] <= '9' {160				i++161			}162			if i > start {163				return string(sTor[start:i])164			}165			return ""166		}167168		if l := digits(); l != "" {169			var err error170			length, err = strconv.Atoi(l)171			if err != nil {172				panic("ufmt: invalid length specification")173			}174		}175176		if i < end && sTor[i] == '.' {177			i++ // skip '.'178			if l := digits(); l != "" {179				var err error180				precision, err = strconv.Atoi(l)181				if err != nil {182					panic("ufmt: invalid precision specification")183				}184			}185		}186187		if i >= end {188			panic("ufmt: invalid format string")189		}190191		verb := sTor[i]192		if verb == '%' {193			p.buf.writeRune('%')194			i++195			continue196		}197198		if argNum >= argLen {199			panic("ufmt: not enough arguments")200		}201		arg := args[argNum]202		argNum++203204		switch verb {205		case 'v':206			writeValue(p, verb, arg)207		case 's':208			writeStringWithLength(p, verb, arg, length)209		case 'c':210			writeChar(p, verb, arg)211		case 'd':212			writeInt(p, verb, arg)213		case 'e', 'E', 'f', 'F', 'g', 'G':214			writeFloatWithPrecision(p, verb, arg, precision)215		case 't':216			writeBool(p, verb, arg)217		case 'x':218			writeHex(p, verb, arg)219		case 'q':220			writeQuotedString(p, verb, arg)221		case 'T':222			writeType(p, arg)223		// % handled before, as it does not consume an argument224		default:225			p.buf.writeString("(unhandled verb: %" + string(verb) + ")")226		}227228		i++229	}230231	if argNum < argLen {232		panic("ufmt: too many arguments")233	}234}235236// writeValue handles %v formatting237func writeValue(p *printer, verb rune, arg any) {238	switch v := arg.(type) {239	case nil:240		p.buf.writeString("<nil>")241	case bool:242		writeBool(p, verb, v)243	case int:244		p.buf.writeString(strconv.Itoa(v))245	case int8:246		p.buf.writeString(strconv.Itoa(int(v)))247	case int16:248		p.buf.writeString(strconv.Itoa(int(v)))249	case int32:250		p.buf.writeString(strconv.Itoa(int(v)))251	case int64:252		p.buf.writeString(strconv.Itoa(int(v)))253	case uint:254		p.buf.writeString(strconv.FormatUint(uint64(v), 10))255	case uint8:256		p.buf.writeString(strconv.FormatUint(uint64(v), 10))257	case uint16:258		p.buf.writeString(strconv.FormatUint(uint64(v), 10))259	case uint32:260		p.buf.writeString(strconv.FormatUint(uint64(v), 10))261	case uint64:262		p.buf.writeString(strconv.FormatUint(v, 10))263	case float64:264		p.buf.writeString(strconv.FormatFloat(v, 'g', -1, 64))265	case string:266		p.buf.writeString(v)267	case []byte:268		p.buf.write(v)269	case []rune:270		p.buf.writeString(string(v))271	case (interface{ String() string }):272		p.buf.writeString(v.String())273	case error:274		p.buf.writeString(v.Error())275	default:276		p.buf.writeString(fallback(verb, v))277	}278}279280// writeStringWithLength handles %s formatting with length specification281func writeStringWithLength(p *printer, verb rune, arg any, length int) {282	var s string283	switch v := arg.(type) {284	case (interface{ String() string }):285		s = v.String()286	case error:287		s = v.Error()288	case string:289		s = v290	default:291		s = fallback(verb, v)292	}293294	if length > 0 && len(s) < length {295		s = strings.Repeat(" ", length-len(s)) + s296	}297	p.buf.writeString(s)298}299300// writeChar handles %c formatting301func writeChar(p *printer, verb rune, arg any) {302	switch v := arg.(type) {303	// rune is int32. Exclude overflowing numeric types and dups (byte, int32):304	case rune:305		p.buf.writeString(string(v))306	case int:307		p.buf.writeRune(rune(v))308	case int8:309		p.buf.writeRune(rune(v))310	case int16:311		p.buf.writeRune(rune(v))312	case uint:313		p.buf.writeRune(rune(v))314	case uint8:315		p.buf.writeRune(rune(v))316	case uint16:317		p.buf.writeRune(rune(v))318	default:319		p.buf.writeString(fallback(verb, v))320	}321}322323// writeInt handles %d formatting324func writeInt(p *printer, verb rune, arg any) {325	switch v := arg.(type) {326	case int:327		p.buf.writeString(strconv.Itoa(v))328	case int8:329		p.buf.writeString(strconv.Itoa(int(v)))330	case int16:331		p.buf.writeString(strconv.Itoa(int(v)))332	case int32:333		p.buf.writeString(strconv.Itoa(int(v)))334	case int64:335		p.buf.writeString(strconv.Itoa(int(v)))336	case uint:337		p.buf.writeString(strconv.FormatUint(uint64(v), 10))338	case uint8:339		p.buf.writeString(strconv.FormatUint(uint64(v), 10))340	case uint16:341		p.buf.writeString(strconv.FormatUint(uint64(v), 10))342	case uint32:343		p.buf.writeString(strconv.FormatUint(uint64(v), 10))344	case uint64:345		p.buf.writeString(strconv.FormatUint(v, 10))346	default:347		p.buf.writeString(fallback(verb, v))348	}349}350351// writeFloatWithPrecision handles floating-point formatting with precision352func writeFloatWithPrecision(p *printer, verb rune, arg any, precision int) {353	switch v := arg.(type) {354	case float64:355		format := byte(verb)356		if format == 'F' {357			format = 'f'358		}359		if precision < 0 {360			switch format {361			case 'e', 'E':362				precision = 2363			default:364				precision = 6365			}366		}367		p.buf = strconv.AppendFloat(p.buf, v, format, precision, 64)368	default:369		p.buf.writeString(fallback(verb, v))370	}371}372373// writeBool handles %t formatting374func writeBool(p *printer, verb rune, arg any) {375	switch v := arg.(type) {376	case bool:377		if v {378			p.buf.writeString("true")379		} else {380			p.buf.writeString("false")381		}382	default:383		p.buf.writeString(fallback(verb, v))384	}385}386387// writeHex handles %x formatting388func writeHex(p *printer, verb rune, arg any) {389	switch v := arg.(type) {390	case uint8:391		p.buf.writeString(strconv.FormatUint(uint64(v), 16))392	default:393		p.buf.writeString("(unhandled)")394	}395}396397// writeQuotedString handles %q formatting398func writeQuotedString(p *printer, verb rune, arg any) {399	switch v := arg.(type) {400	case string:401		p.buf.writeString(strconv.Quote(v))402	default:403		p.buf.writeString("(unhandled)")404	}405}406407// writeType handles %T formatting408func writeType(p *printer, arg any) {409	switch arg.(type) {410	case bool:411		p.buf.writeString("bool")412	case int:413		p.buf.writeString("int")414	case int8:415		p.buf.writeString("int8")416	case int16:417		p.buf.writeString("int16")418	case int32:419		p.buf.writeString("int32")420	case int64:421		p.buf.writeString("int64")422	case uint:423		p.buf.writeString("uint")424	case uint8:425		p.buf.writeString("uint8")426	case uint16:427		p.buf.writeString("uint16")428	case uint32:429		p.buf.writeString("uint32")430	case uint64:431		p.buf.writeString("uint64")432	case string:433		p.buf.writeString("string")434	case []byte:435		p.buf.writeString("[]byte")436	case []rune:437		p.buf.writeString("[]rune")438	default:439		p.buf.writeString("unknown")440	}441}442443// Fprintf formats according to a format specifier and writes to w.444// Returns the number of bytes written and any write error encountered.445func Fprintf(w io.Writer, format string, a ...any) (n int, err error) {446	p := newPrinter()447	p.doPrintf(format, a)448	return w.Write(p.buf)449}450451// Printf formats according to a format specifier and writes to standard output.452// Returns the number of bytes written and any write error encountered.453//454// XXX: Replace with os.Stdout handling when available.455func Printf(format string, a ...any) (n int, err error) {456	var out strings.Builder457	n, err = Fprintf(&out, format, a...)458	print(out.String())459	return n, err460}461462// Appendf formats according to a format specifier, appends the result to the byte463// slice, and returns the updated slice.464func Appendf(b []byte, format string, a ...any) []byte {465	p := newPrinter()466	p.doPrintf(format, a)467	return append(b, p.buf...)468}469470// Fprint formats using default formats and writes to w.471// Spaces are added between arguments.472// Returns the number of bytes written and any write error encountered.473func Fprint(w io.Writer, a ...any) (n int, err error) {474	p := newPrinter()475	p.doPrint(a)476	return w.Write(p.buf)477}478479// Print formats using default formats and writes to standard output.480// Spaces are added between arguments.481// Returns the number of bytes written and any write error encountered.482//483// XXX: Replace with os.Stdout handling when available.484func Print(a ...any) (n int, err error) {485	var out strings.Builder486	n, err = Fprint(&out, a...)487	print(out.String())488	return n, err489}490491// Append formats using default formats, appends to b, and returns the updated slice.492// Spaces are added between arguments.493func Append(b []byte, a ...any) []byte {494	p := newPrinter()495	p.doPrint(a)496	return append(b, p.buf...)497}498499// Fprintln formats using default formats and writes to w with newline.500// Returns the number of bytes written and any write error encountered.501func Fprintln(w io.Writer, a ...any) (n int, err error) {502	p := newPrinter()503	p.doPrintln(a)504	return w.Write(p.buf)505}506507// Println formats using default formats and writes to standard output with newline.508// Returns the number of bytes written and any write error encountered.509//510// XXX: Replace with os.Stdout handling when available.511func Println(a ...any) (n int, err error) {512	var out strings.Builder513	n, err = Fprintln(&out, a...)514	print(out.String())515	return n, err516}517518// Sprintln formats using default formats and returns the string with newline.519// Spaces are always added between arguments.520func Sprintln(a ...any) string {521	p := newPrinter()522	p.doPrintln(a)523	return string(p.buf)524}525526// Appendln formats using default formats, appends to b, and returns the updated slice.527// Appends a newline after the last argument.528func Appendln(b []byte, a ...any) []byte {529	p := newPrinter()530	p.doPrintln(a)531	return append(b, p.buf...)532}533534// This function is used to mimic Go's fmt.Sprintf535// specific behaviour of showing verb/type mismatches,536// where for example:537//538//	fmt.Sprintf("%d", "foo") gives "%!d(string=foo)"539//540// Here:541//542//	fallback("s", 8) -> "%!s(int=8)"543//	fallback("d", nil) -> "%!d(<nil>)", and so on.f544func fallback(verb rune, arg any) string {545	var s string546	switch v := arg.(type) {547	case string:548		s = "string=" + v549	case (interface{ String() string }):550		s = "string=" + v.String()551	case error:552		// note: also "string=" in Go fmt553		s = "string=" + v.Error()554	case float64:555		s = "float64=" + Sprintf("%f", v)556	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:557		// note: rune, byte would be dups, being aliases558		if typename, e := typeToString(v); e == nil {559			s = typename + "=" + Sprintf("%d", v)560		} else {561			panic("ufmt: unexpected type error")562		}563	case bool:564		s = "bool=" + strconv.FormatBool(v)565	case nil:566		s = "<nil>"567	default:568		s = "(unhandled)"569	}570	return "%!" + string(verb) + "(" + s + ")"571}572573// typeToString returns the name of basic Go types as string.574func typeToString(v any) (string, error) {575	switch v.(type) {576	case string:577		return "string", nil578	case int:579		return "int", nil580	case int8:581		return "int8", nil582	case int16:583		return "int16", nil584	case int32:585		return "int32", nil586	case int64:587		return "int64", nil588	case uint:589		return "uint", nil590	case uint8:591		return "uint8", nil592	case uint16:593		return "uint16", nil594	case uint32:595		return "uint32", nil596	case uint64:597		return "uint64", nil598	case float32:599		return "float32", nil600	case float64:601		return "float64", nil602	case bool:603		return "bool", nil604	default:605		return "", errors.New("unsupported type")606	}607}608609// errMsg implements the error interface for formatted error strings.610type errMsg struct {611	msg string612}613614// Error returns the formatted error message.615func (e *errMsg) Error() string {616	return e.msg617}618619// Errorf formats according to a format specifier and returns an error value.620// Supports the same verbs as Sprintf. See Sprintf documentation for details.621func Errorf(format string, args ...any) error {622	return &errMsg{Sprintf(format, args...)}623}624

Functions

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

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