Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid use of fmt in the main package. #456

Merged
merged 3 commits into from
Feb 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions answer.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,13 @@ func (pc PipelineClient) Brand() Brand {
func (pc PipelineClient) Shutdown() {
}

func (pc PipelineClient) String() string {
return "PipelineClient{transform: " +
str.Slice(pc.transform) +
", promise: 0x" + str.PtrToHex(pc.p) +
"}"
}

// A PipelineOp describes a step in transforming a pipeline.
// It maps closely with the PromisedAnswer.Op struct in rpc.capnp.
type PipelineOp struct {
Expand Down
12 changes: 9 additions & 3 deletions capability.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package capnp
import (
"context"
"errors"
"fmt"
"runtime"
"strconv"
"sync"
Expand Down Expand Up @@ -606,9 +605,9 @@ func (c Client) String() string {
}
var s string
if c.h.isResolved() {
s = fmt.Sprintf("<client %T@%p>", c.h.ClientHook, c.h)
s = "<client " + c.h.ClientHook.String() + ">"
} else {
s = fmt.Sprintf("<unresolved client %T@%p>", c.h.ClientHook, c.h)
s = "<unresolved client " + c.h.ClientHook.String() + ">"
}
c.h.mu.Unlock()
c.mu.Unlock()
Expand Down Expand Up @@ -876,6 +875,9 @@ type ClientHook interface {
// Shutdown is undefined. It is expected for the ClientHook to reject
// any outstanding call futures.
Shutdown()

// String formats the hook as a string (same as fmt.Stringer)
String() string
}

// Send is the input to ClientHook.Send.
Expand Down Expand Up @@ -1049,4 +1051,8 @@ func (ec errorClient) Brand() Brand {
func (ec errorClient) Shutdown() {
}

func (ec errorClient) String() string {
return "errorClient{" + ec.e.Error() + "}"
}

var closedSignal = make(chan struct{})
4 changes: 4 additions & 0 deletions capability_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@ type dummyHook struct {
shutdowns int
}

func (dh *dummyHook) String() string {
return "&dummyHook{}"
}

func (dh *dummyHook) Send(_ context.Context, s Send) (*Answer, ReleaseFunc) {
dh.calls++
return ImmediateAnswer(s.Method, newEmptyStruct()), func() {}
Expand Down
6 changes: 4 additions & 2 deletions flowcontrol/fixed.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package flowcontrol

import (
"context"
"fmt"

"capnproto.org/go/capnp/v3/internal/str"
"golang.org/x/sync/semaphore"
)

Expand All @@ -26,7 +26,9 @@ func (fl *fixedLimiter) StartMessage(ctx context.Context, size uint64) (gotRespo
// reservation on the semaphore. We can't return an error because it
// is currently ignored by the caller.
if int64(size) > fl.size {
panic(fmt.Sprintf("StartMessage(): message size %d is too large (max %d)", size, fl.size))
panic("StartMessage(): message size " +
str.Utod(size) +
" is too large (max " + str.Itod(fl.size) + ")")
}

if err = fl.sem.Acquire(ctx, int64(size)); err == nil {
Expand Down
32 changes: 30 additions & 2 deletions internal/str/str.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
// of environments that care about minimizing executable size.
package str

import "strconv"
import (
"strconv"
"strings"

"unsafe" // Only for formatting pointers as integers; we don't actually do anything unsafe.
)

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

func PtrToHex[T any](p *T) string {
return UToHex(uintptr(unsafe.Pointer(p)))
}

// ZeroPad pads value to the left with zeros, making the resulting string
// count bytes long.
func ZeroPad(count int, value string) string {
Expand All @@ -34,8 +43,27 @@ func ZeroPad(count int, value string) string {
return string(buf)
}

// Slice formats a slice of values which themselves implement Stringer.
func Slice[T Stringer](s []T) string {
var b strings.Builder
b.WriteRune('{')
for i, v := range s {
if i > 0 {
b.WriteString(", ")
}
b.WriteString(v.String())
}
b.WriteRune('}')
return b.String()
}

// Stringer is equivalent to fmt.Stringer
type Stringer interface {
String() string
}

type Uint interface {
~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uint
~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uint | ~uintptr
}

type Int interface {
Expand Down
4 changes: 4 additions & 0 deletions rpc/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ type embargo struct {
lifted chan struct{}
}

func (e embargo) String() string {
return "embargo{c: " + e.c.String() + ", 0x" + str.PtrToHex(e.p) + "}"
}

// embargo creates a new embargoed client, stealing the reference.
//
// The caller must be holding onto c.mu.
Expand Down
5 changes: 5 additions & 0 deletions rpc/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"

"capnproto.org/go/capnp/v3"
"capnproto.org/go/capnp/v3/internal/str"
"capnproto.org/go/capnp/v3/internal/syncutil"
rpccp "capnproto.org/go/capnp/v3/std/capnp/rpc"
)
Expand Down Expand Up @@ -84,6 +85,10 @@ type importClient struct {
generation uint64
}

func (ic *importClient) String() string {
return "importClient{c: 0x" + str.PtrToHex(ic.c) + ", id: " + str.Utod(ic.id) + "}"
}

func (ic *importClient) Send(ctx context.Context, s capnp.Send) (*capnp.Answer, capnp.ReleaseFunc) {
return withLockedConn2(ic.c, func(c *lockedConn) (*capnp.Answer, capnp.ReleaseFunc) {
if !c.startTask() {
Expand Down
4 changes: 4 additions & 0 deletions rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ type bootstrapClient struct {
cancel context.CancelFunc
}

func (bc bootstrapClient) String() string {
return "bootstrapClient{c: " + bc.c.String() + "}"
}

func (bc bootstrapClient) Send(ctx context.Context, s capnp.Send) (*capnp.Answer, capnp.ReleaseFunc) {
return bc.c.SendCall(ctx, s)
}
Expand Down
5 changes: 5 additions & 0 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"capnproto.org/go/capnp/v3"
"capnproto.org/go/capnp/v3/exc"
"capnproto.org/go/capnp/v3/exp/mpsc"
"capnproto.org/go/capnp/v3/internal/str"
)

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

func (s *Server) String() string {
return "*Server@0x" + str.PtrToHex(s)
}

// New returns a client hook that makes calls to a set of methods.
// If shutdown is nil then the server's shutdown is a no-op. The server
// guarantees message delivery order by blocking each call on the
Expand Down