-
-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #547 from alrs/util
Move zenhack.net/go/util into go-capnp repository
- Loading branch information
Showing
30 changed files
with
1,118 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
This directory contains misc. Go utility packages that Ian Denhardt wrote as he | ||
needed them for other projects. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package util | ||
|
||
// Chkfatal panics if err is not nil | ||
func Chkfatal(err error) { | ||
if err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
// Must panics if err != nil, otherwise returns value. | ||
func Must[T any](value T, err error) T { | ||
Chkfatal(err) | ||
return value | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package util | ||
|
||
import ( | ||
"errors" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestChkfatal(t *testing.T) { | ||
assert.NotPanics(t, func() { | ||
Chkfatal(nil) | ||
}, "Chkfatal does not panic on a nil error.") | ||
|
||
assert.Panics(t, func() { | ||
Chkfatal(errors.New("Some error.")) | ||
}, "Chkfatal panics on a non-nil error.") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Package debugging exports various helpers useful when debugging. In general, | ||
// code from this package should not be included in production builds. | ||
package debugging | ||
|
||
import "runtime" | ||
|
||
// Wrapper around runtime.Stack, which allocates a buffer and returns the stack | ||
// trace as a string. Stack traces over 1MB will be truncated. | ||
func StackString(all bool) string { | ||
var buf [1e6]byte | ||
n := runtime.Stack(buf[:], all) | ||
return string(buf[:n]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Package deferred provides tools for deferring actions | ||
// to be run at a later time. These can be thought of as | ||
// an extension and generalization of the language's built-in | ||
// defer statement. | ||
package deferred | ||
|
||
// A Queue is a queue of actions to run at some later time. | ||
// The actions will be run in the order they are added with | ||
// Defer. Note that this is different from the language's | ||
// built-in defer statement, which runs actions in reverse | ||
// order (future versions of this package may add a Stack | ||
// type to support those semantics). | ||
// | ||
// The zero value is an empty queue. | ||
// | ||
// The advantage of this vs. built-in defer is that it needn't | ||
// be tied to the scope of a single function; for example, | ||
// you can write code like: | ||
// | ||
// q := &Queue{} | ||
// defer q.Run() | ||
// f(q) // pass the queue to a subroutine, which may queue | ||
// // up actions to be run after *this* function returns. | ||
type Queue []func() | ||
|
||
// Run runs all deferred actions, in the order they were added. | ||
func (q *Queue) Run() { | ||
funcs := *q | ||
for i, f := range funcs { | ||
if f != nil { | ||
f() | ||
funcs[i] = nil | ||
} | ||
} | ||
} | ||
|
||
// Defer adds f to the list of functions to call when Run() | ||
// is invoked. | ||
func (q *Queue) Defer(f func()) { | ||
*q = append(*q, f) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// Package exn provides an exception-like mechanism. | ||
// | ||
// It is a bit easier to reason about than standard exceptions, since | ||
// not any code can throw, only code given access to a throw callback. | ||
// See the docs for Try. | ||
package exn | ||
|
||
// exn is a wrapper type used to distinguish values this package passes | ||
// to panic() from anything else that might be passed to panic by | ||
// unrelated code. | ||
type exn struct { | ||
err error | ||
} | ||
|
||
// An alias for the type of the callback provided by Try. | ||
type Thrower = func(error, ...string) | ||
|
||
// Try invokes f, which is a callback with type: | ||
// | ||
// func(throw Thrower) T | ||
// | ||
// Thrower is an alias for func(error, ...string). | ||
// | ||
// If f returns normally, Try returns the value f returned and a nil | ||
// error. | ||
// | ||
// If f invokes throw with a non-nil error, f's execution is | ||
// terminated, and Try returns the zero value for T and the | ||
// error that was passed to throw. | ||
// | ||
// If f invokes throw with a nil argument, throw returns normally | ||
// without terminating f. This is so that error handling code can | ||
// pass errors to throw unconditionally, like: | ||
// | ||
// v, err := foo() | ||
// throw(err) | ||
// | ||
// f must not store throw or otherwise cause it to be invoked after | ||
// Try returns. | ||
// | ||
// Callers may pass additonal string arguments to throw, which will | ||
// wrap the error with additional context, i.e. throw(err, "something") | ||
// is equivalent to throw(Wrap("something", err)) | ||
func Try[T any](f func(Thrower) T) (result T, err error) { | ||
throw := func(e error, context ...string) { | ||
if e == nil { | ||
return | ||
} | ||
for i := len(context) - 1; i >= 0; i-- { | ||
e = Wrap(context[i], e) | ||
} | ||
panic(exn{err: e}) | ||
} | ||
finishedCall := false | ||
defer func() { | ||
if finishedCall { | ||
return | ||
} | ||
|
||
panicVal := recover() | ||
if e, ok := panicVal.(exn); ok { | ||
err = e.err | ||
} else { | ||
panic(panicVal) | ||
} | ||
}() | ||
result = f(throw) | ||
finishedCall = true | ||
return | ||
} | ||
|
||
// Try0 is like Try, but f does not return a value, and Try0 only returns | ||
// an error. | ||
func Try0(f func(Thrower)) error { | ||
_, err := Try(func(throw Thrower) struct{} { | ||
f(throw) | ||
return struct{}{} | ||
}) | ||
return err | ||
} | ||
|
||
// Try2 is like Try, but with two values instead of 1. | ||
func Try2[A, B any](f func(Thrower) (A, B)) (A, B, error) { | ||
r, err := Try(func(throw Thrower) pair[A, B] { | ||
a, b := f(throw) | ||
return pair[A, B]{a: a, b: b} | ||
}) | ||
return r.a, r.b, err | ||
} | ||
|
||
// TODO: move into its own package. | ||
type pair[A, B any] struct { | ||
a A | ||
b B | ||
} |
Oops, something went wrong.