Skip to content

Commit f9f1b3d

Browse files
committed
Avoid use of fmt in the main package.
This adds a String() method to ClientHook so we can avoid using fmt for that, then removes the last use of fmt in the main package, per capnproto#364. Before closing that issue, I think I'd still like to get it out of the flowcontrol package hierarchy at least, and maybe elsewhere if practical.
1 parent 285a677 commit f9f1b3d

File tree

7 files changed

+64
-5
lines changed

7 files changed

+64
-5
lines changed

answer.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,13 @@ func (pc PipelineClient) Brand() Brand {
540540
func (pc PipelineClient) Shutdown() {
541541
}
542542

543+
func (pc PipelineClient) String() string {
544+
return "PipelineClient{transform: " +
545+
str.Slice(pc.transform) +
546+
", promise: 0x" + str.PtrToHex(pc.p) +
547+
"}"
548+
}
549+
543550
// A PipelineOp describes a step in transforming a pipeline.
544551
// It maps closely with the PromisedAnswer.Op struct in rpc.capnp.
545552
type PipelineOp struct {

capability.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package capnp
33
import (
44
"context"
55
"errors"
6-
"fmt"
76
"runtime"
87
"strconv"
98
"sync"
@@ -606,9 +605,9 @@ func (c Client) String() string {
606605
}
607606
var s string
608607
if c.h.isResolved() {
609-
s = fmt.Sprintf("<client %T@%p>", c.h.ClientHook, c.h)
608+
s = "<client " + c.h.ClientHook.String() + ">"
610609
} else {
611-
s = fmt.Sprintf("<unresolved client %T@%p>", c.h.ClientHook, c.h)
610+
s = "<unresolved client " + c.h.ClientHook.String() + ">"
612611
}
613612
c.h.mu.Unlock()
614613
c.mu.Unlock()
@@ -876,6 +875,9 @@ type ClientHook interface {
876875
// Shutdown is undefined. It is expected for the ClientHook to reject
877876
// any outstanding call futures.
878877
Shutdown()
878+
879+
// String formats the hook as a string (same as fmt.Stringer)
880+
String() string
879881
}
880882

881883
// Send is the input to ClientHook.Send.
@@ -1049,4 +1051,8 @@ func (ec errorClient) Brand() Brand {
10491051
func (ec errorClient) Shutdown() {
10501052
}
10511053

1054+
func (ec errorClient) String() string {
1055+
return "errorClient{" + ec.e.Error() + "}"
1056+
}
1057+
10521058
var closedSignal = make(chan struct{})

internal/str/str.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22
// of environments that care about minimizing executable size.
33
package str
44

5-
import "strconv"
5+
import (
6+
"strconv"
7+
"strings"
8+
9+
"unsafe" // Only for formatting pointers as integers; we don't actually do anything unsafe.
10+
)
611

712
// Utod formats unsigned integers as decimals.
813
func Utod[T Uint](n T) string {
@@ -19,6 +24,10 @@ func UToHex[T Uint](n T) string {
1924
return strconv.FormatUint(uint64(n), 16)
2025
}
2126

27+
func PtrToHex[T any](p *T) string {
28+
return UToHex(uintptr(unsafe.Pointer(p)))
29+
}
30+
2231
// ZeroPad pads value to the left with zeros, making the resulting string
2332
// count bytes long.
2433
func ZeroPad(count int, value string) string {
@@ -34,8 +43,27 @@ func ZeroPad(count int, value string) string {
3443
return string(buf)
3544
}
3645

46+
// Slice formats a slice of values which themselves implement Stringer.
47+
func Slice[T Stringer](s []T) string {
48+
var b strings.Builder
49+
b.WriteRune('{')
50+
for i, v := range s {
51+
if i > 0 {
52+
b.WriteString(", ")
53+
}
54+
b.WriteString(v.String())
55+
}
56+
b.WriteRune('}')
57+
return b.String()
58+
}
59+
60+
// Stringer is equivalent to fmt.Stringer
61+
type Stringer interface {
62+
String() string
63+
}
64+
3765
type Uint interface {
38-
~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uint
66+
~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uint | ~uintptr
3967
}
4068

4169
type Int interface {

rpc/export.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ type embargo struct {
208208
lifted chan struct{}
209209
}
210210

211+
func (e embargo) String() string {
212+
return "embargo{c: " + e.c.String() + ", 0x" + str.PtrToHex(e.p) + "}"
213+
}
214+
211215
// embargo creates a new embargoed client, stealing the reference.
212216
//
213217
// The caller must be holding onto c.mu.

rpc/import.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66

77
"capnproto.org/go/capnp/v3"
8+
"capnproto.org/go/capnp/v3/internal/str"
89
"capnproto.org/go/capnp/v3/internal/syncutil"
910
rpccp "capnproto.org/go/capnp/v3/std/capnp/rpc"
1011
)
@@ -84,6 +85,10 @@ type importClient struct {
8485
generation uint64
8586
}
8687

88+
func (ic *importClient) String() string {
89+
return "importClient{c: 0x" + str.PtrToHex(ic.c) + ", id: " + str.Utod(ic.id) + "}"
90+
}
91+
8792
func (ic *importClient) Send(ctx context.Context, s capnp.Send) (*capnp.Answer, capnp.ReleaseFunc) {
8893
return withLockedConn2(ic.c, func(c *lockedConn) (*capnp.Answer, capnp.ReleaseFunc) {
8994
if !c.startTask() {

rpc/rpc.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ type bootstrapClient struct {
332332
cancel context.CancelFunc
333333
}
334334

335+
func (bc bootstrapClient) String() string {
336+
return "bootstrapClient{c: " + bc.c.String() + "}"
337+
}
338+
335339
func (bc bootstrapClient) Send(ctx context.Context, s capnp.Send) (*capnp.Answer, capnp.ReleaseFunc) {
336340
return bc.c.SendCall(ctx, s)
337341
}

server/server.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"capnproto.org/go/capnp/v3"
1111
"capnproto.org/go/capnp/v3/exc"
1212
"capnproto.org/go/capnp/v3/exp/mpsc"
13+
"capnproto.org/go/capnp/v3/internal/str"
1314
)
1415

1516
// A Method describes a single capability method on a server object.
@@ -104,6 +105,10 @@ type Server struct {
104105
HandleUnknownMethod func(m capnp.Method) *Method
105106
}
106107

108+
func (s *Server) String() string {
109+
return "*Server@0x" + str.PtrToHex(s)
110+
}
111+
107112
// New returns a client hook that makes calls to a set of methods.
108113
// If shutdown is nil then the server's shutdown is a no-op. The server
109114
// guarantees message delivery order by blocking each call on the

0 commit comments

Comments
 (0)