func Append
Append formats its operands as Sprint does and appends the result to b.
Package ufmt is a preview of gno.land/p/nt/ufmt/v2, published here before that path exists.
This is ufmt v2, published here before its real path exists. The expected
home is gno.land/p/nt/ufmt/v2, which is not published yet.
Until it is, import:
1import "gno.land/p/moul/vendor/nt/ufmt/v2"
When gno.land/p/nt/ufmt/v2 goes live, change the import and nothing else.
This path is then frozen: it keeps working, it never gets another fix.
p/nt/ufmt/v0 knows a handful of verbs and no flags, and it
fails quietly. Sprintf("0x%08X", pc) prints 0x(unhandled verb: %X),
Sprintf("%08x", w) prints (unhandled), and Sprintf("%03d", 7) prints 7.
r/moul/x/vm/riscvdemo shipped a register dump
that was nothing but those.
v2 is Go's fmt, as far as gno can follow it:
| flags | + - # 0 |
| width, precision | %8d, %.2f, %*d, %.*f, %.3s in runes |
| argument indexes | %[2]d %[1]s, %[1]*[2]d |
| integers | %b %c %d %o %O %q %x %X %U, every int and uint type |
| floats | %b %e %E %f %F %g %G %x %X, float32 and float64 |
strings, []byte |
%s %q %x %X, % x, %#q |
| methods | Formatter, GoStringer, error, Stringer, in Go's order |
| errors | Errorf with %w, one or several, seen by errors.Is |
| composites | slices of the basic types, []any, map[string]T sorted by key |
A mistake is printed, never panicked, with Go's strings: %!d(string=hi),
%!d(MISSING), %!(EXTRA int=1), %!(NOVERB). A Render cannot be taken down
by a format string.
gofmt_test.gno is 210 cases whose expected output was produced by running
each one through Go's fmt.Sprintf (go1.27.1), so a failure there is, by
construction, a place v2 and Go disagree. It also costs less gas than v0 on the
calls realms make most: about 211k against 254k per Sprintf("id %d is %s (%t)", ...), measured with gno test.
gno has no reflect. A struct, a pointer, or a named type without a String
method prints (unhandled), and %T names only the types it knows. Give the
type a String method. %p is not supported.
Mostly a change of import, with these differences, all of them toward Go:
Sprint adds a space only between two operands that are both non-strings.%v and Sprint (3.14, not
3.140000), and %e defaults to 6 digits.%v of a []byte is [104 105]; use %s for the text.error wins over String when a value has both.Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.
⚠️ Disclaimer: provided as-is, without warranty; not security-audited. Full disclaimer: DISCLAIMER.
Package ufmt is a preview of gno.land/p/nt/ufmt/v2, published here before that path exists.
This is v2 of ufmt. It is not yet published at its expected path, gno.land/p/nt/ufmt/v2. Until it is, import it from gno.land/p/moul/vendor/nt/ufmt/v2; once gno.land/p/nt/ufmt/v2 is live, switch the import and nothing else, because the API is meant to be the same. This path is then frozen and never updated again.
v0 (gno.land/p/nt/ufmt/v0) supports a handful of verbs and no flags, so "%08x", "%X" and "%-10s" print "(unhandled)" or drop their padding without a word. v2 follows Go's fmt instead: the same flags, widths, precisions and verbs, and the same error strings in place of panics. Where it cannot follow Go, because gno has no reflect, it says so below.
Supported, as in Go's fmt:
1flags '+' '-' '#' ' ' '0'
2width %8d, %*d, and a negative * width left-justifies
3precision %.2f, %.*f, %.3s (in runes)
4indexes %[2]d %[1]s, %[1]*[2]d
5general %v %+v %#v %T %%
6bool %t
7integer %b %c %d %o %O %q %x %X %U, every int and uint type
8float %b %e %E %f %F %g %G %x %X, float32 and float64
9string %s %q %x %X, and []byte the same way
10errors %w in Errorf, unwrapped by errors.Unwrap and errors.Is
11methods Formatter, GoStringer, error, Stringer, in Go's order
12composite []T of the basic types, []any, []error, and map[string]T
13 with its keys sorted, as Go prints them
Errors are written into the output, never panicked: "%!d(string=hi)" for a wrong type, "%!d(MISSING)" for a missing argument, "%!(EXTRA int=1)" for an unused one, "%!(NOVERB)" for a trailing '%'.
What gno cannot do, and what v2 prints instead:
What changed from v0, so a migration is a review and not a find-and-replace:
Append formats its operands as Sprint does and appends the result to b.
Appendf formats according to a format specifier and appends the result to b.
Appendln formats its operands as Sprintln does and appends the result to b.
Errorf formats according to a format specifier and returns the string as an error. Each %w operand must be an error; it is printed as %v and returned by the error's Unwrap method, so errors.Is and errors.Unwrap can find it. One %w gives an Unwrap() error, several give an Unwrap() []error, as in Go.
Fprint formats its operands as Sprint does and writes to w.
Fprintf formats according to a format specifier and writes to w.
Fprintln formats its operands as Sprintln does and writes to w.
Print formats its operands as Sprint does and prints the result.
Printf formats according to a format specifier and prints the result with the print builtin, which is what a test or a filetest captures.
Println formats its operands as Sprintln does and prints the result.
Sprint formats its operands with %v and returns the string. A space is added between two operands when neither is a string.
Sprintf formats according to a format specifier and returns the string.
Sprintln formats its operands with %v, always separated by a space, and appends a newline.
Formatter is implemented by a value that formats itself. Format is called for every verb, and its output replaces what ufmt would have printed.
GoStringer is implemented by a value that has a Go-syntax form, used for %#v.
1type State interface {
2 // Write emits formatted output.
3 Write(b []byte) (n int, err error)
4 // Width returns the width and whether one was set.
5 Width() (wid int, ok bool)
6 // Precision returns the precision and whether one was set.
7 Precision() (prec int, ok bool)
8 // Flag reports whether the flag c, a character, was set.
9 Flag(c int) bool
10}State is what a Formatter's Format method is handed: the flags, width and precision of the verb being printed, and somewhere to write.
Stringer is implemented by a value that has a natural string form. It is used for %v, %s, %q, %x and %X, and by Print.