A collection of random Go packages.
The iter
package builds on the standard iter
package.
It re-exports Seq
and Seq2
for convenience and adds Seq3
.
It adds sequence creation functions such as Empty
, Singleton
, and Values
.
var seq Seq[int] = iter.Empty[int]()
var seq Seq[int] = iter.Singleton(69)
var seq Seq[int] = iter.Values(69, 420)
It also adds various sequence operations such as Map
, Fold
, and Filter
.
var seq Seq[int] = iter.Values(69, 420)
// [70, 421]
mapped := iter.Map(seq, func(i int) int {
return i + 1
})
// 489
sum := iter.Fold(seq, func(acc, i int) {
return acc + i
}, 0)
// [69]
filtered := iter.Filter(seq, func(i int) bool {
return i != 420
})
Primarily re-exports functions and types for convenience.
Due to Go not currently supporting generic type aliases, these functions adapt the standard iter
seq to this module's iter
package.
func Test(seq iter.Seq2[string, int]) {
var m map[string]int = maps.Collect(seq)
}
The maps
package also adds AppendSeq
for appending a map
to a Seq2
.
seq := maps.All(map[string]string{"foo": "bar"})
// {"foo": "bar", "bin": "baz"}
seq = maps.AppendSeq(seq, map[string]string{"bin": "baz"})
The result
pakcage adds the Result
type representing either success or error.
It also adds various result operations such as Map
and Bind
.
func main() {
var r Result[int] = func() (int, error) {
return 420, nil
}
r = result.Map(r, func(x int) int {
return x+1
})
}
The slices
package re-exports functions and types from the standard slices
package for convenience.
Due to Go not currently supporting generic type aliases, these functions adapt the standard slices
seq to this module's slices
package.
The fs
packages expands on github.com/spf13/afero
by adding more afero.Fs
implementations as well as various afero.Fs
utility functions.
The context
package adds the context.Fs
interface for filesystem implementations that accept a context.Context
per operation.
It has a basic test suite and generally works but should be considered a 🚧 work in progress 🚧.
The context
package re-exports various functions and types from the standard context
packge for convenience.
Currently the creation functions focus on adapting external context.Fs
implementations to an afero.Fs
to be used with the other utility functions.
var base context.Fs = mypkg.NewEffectfulFs()
fs := context.BackgroundFs(base)
var accessor context.AccessorFunc = func() context.Context {
return context.Background()
}
// Equivalent to `context.BackgroundFs`
fs := context.NewFs(base, accessor)
The context.AferoFs
interface is a union of afero.Fs
and context.Fs
, i.e. exposing both fs.Create
and fs.CreateContext
.
I'm not sure if this actually has any value but it exists.
The context.Discard
function adapts an afero.Fs
to a context.AferoFs
by ignoring the context.Context
argument.
base := afero.NewMemMapFs()
var fs context.AferoFs = context.Discard(base)
The docker
package adds a docker afero.Fs
implementation for operating on the filesystem of a container.
client := client.NewClientWithOpts(client.FromEnv)
fs := docker.NewFs(client, "my-container-id")
The filter
package adds a filtering implementation of afero.Fs
similar to afero.RegExpFs
at accepts a predicate instead.
base := afero.NewMemMapFs()
fs := filter.NewFs(base, func(path string) bool {
return filepath.Ext(path) == ".go"
})
The github
package adds multiple implementations of afero.Fs
for interacting with the GitHub API as if it were a filesystem.
In general it can turn a GitHub url into an afero.Fs
.
fs := github.NewFs(github.NewClient(nil))
file, _ := fs.Open("https://github.com/unmango")
// ["go", "thecluster", "pulumi-baremetal", ...]
file.Readdirnames(420)
The ignore
package adds a filtering afero.Fs
that accepts a .gitignore
file and ignores paths matched by it.
base := afero.NewMemMapFs()
gitignore, _ := os.Open("path/to/my/.gitignore")
fs, _ := ignore.NewFsFromGitIgnoreReader(base, gitignore)
The testing
package adds helper stubs for mocking filesystems in tests.
fs := &testing.Fs{
CreateFunc: func(name string) (afero.File, error) {
return nil, errors.New("simulated error")
}
}
The writer
package adds a readonly afero.Fs
implementation that dumps all file writes to the provided io.Writer
.
Currently paths are ignored and there are no delimeters separating files.
buf := &bytes.Buffer{}
fs := writer.NewFs(buf)
_ = afero.WriteFile(fs, "test.txt", []byte("testing"), os.ModePerm)
_ = afero.WriteFile(fs, "other.txt", []byte("blah"), os.ModePerm)
// "testingblah"
buf.String()
The rx
package attempts to implement the observable and signal patterns for reactive programming in go.
Both observable
and signal
should be considered a 🚧 work in progress 🚧, but the observable
package is generally usable.
var obs rx.Observable[int] = subject.New[int]()
sub := obs.Subscribe(observer.Lift(func(i int) {
fmt.Println(i)
}))
defer sub()
obs.OnNext(69)
obs.OnComplete()
The cmd
package contains CLI utilities exposed by the repo.
Currently the only published tool is devops
which assists with listing files for make
targets.
devops list --go
# cmd/devops/main.go
# devops/cmd/list.go
# fp/constraint/constraints.go
# ...
bin/my-tool: $(shell devops list --go --exclude-tests)
go build -o $@
I stand on the shoulders of giants. A lot of this is inspired by the works of others, be sure to check out these repos as well. (They're much smarter than me)