| Don't repeat yourself, every piece of knowledge must have a single, unambiguous, authoritative representation within a system. |
|---|
- Installation
- Array/Slice Utilities
- Map Utilities
- Concurrency
- Time/Duration
- UUID Generation
- Error Handling
- Backoff/Retry
- Rate Limiting
- Clock Interface
- Configuration
- Deep Copy
- Container Detection
- Graceful Shutdown
- Home Directory
- IO Utilities
- Key Management
- Pattern Matching
- Selector/Operators
- String/Bytes Conversion
- Generic Utilities
- Sub-packages
go get go.zoe.im/xReports whether target is present in items.
nums := []int{1, 2, 3, 4, 5}
if x.Contains(nums, 3) {
fmt.Println("found 3")
}Reports whether any element satisfies the predicate.
hasAlice := x.ContainsFunc(users, func(u User) bool {
return u.Name == "Alice"
})Returns elements that satisfy the predicate.
evens := x.Filter(nums, func(n int) bool {
return n%2 == 0
})Returns transformed elements.
doubled := x.Map(nums, func(n int) int {
return n * 2
})m := map[string]int{"a": 1, "b": 2}
keys := x.Keys(m) // ["a", "b"]
values := x.Values(m) // [1, 2]Iterates with early termination.
x.Range(m, func(k string, v int) bool {
fmt.Printf("%s: %d\n", k, v)
return true
})Updates map and returns changed/deleted entries.
changed, deleted := x.UpdateMap(original, inputs, convertFn, keyFn, false)Type-safe generic concurrent map.
var cache x.SyncMap[string, int]
cache.Store("key", 42)
value, ok := cache.Load("key")Wrapper with JSON/YAML marshaling support.
type Config struct {
Timeout x.Duration `json:"timeout"`
}
// JSON: {"timeout": "30s"}Execute with timeout, returns true if timed out.
timeout := x.RunWithTimeout(func(exit *bool) {
for !*exit { /* work */ }
}, 5*time.Second)uuid := x.NewUUID()
fmt.Println(uuid.String())
parsed, err := x.ParseUUID("550e8400-e29b-41d4-a716-446655440000")Aggregates multiple errors.
var errs x.Errors
errs.Add(errors.New("error 1"))
errs.Add(errors.New("error 2"))
if !errs.IsNil() {
fmt.Println(errs.Error())
}Execute operations with configurable retry strategies and backoff algorithms.
ctx := context.Background()
// Basic retry with exponential backoff
backoff := x.NewExponentialBackoff(100*time.Millisecond, 10*time.Second)
err := x.Retry(ctx, backoff, func(ctx context.Context) error {
if err := doSomething(); err != nil {
return x.RetryableError(err) // Mark as retryable
}
return nil // Success
})
// Convenience function
err = x.Exponential(ctx, 100*time.Millisecond, 10*time.Second, func(ctx context.Context) error {
return x.RetryableError(db.Ping())
})// Constant: 1s -> 1s -> 1s -> 1s
b := x.NewConstantBackoff(1 * time.Second)
// Exponential: 1s -> 2s -> 4s -> 8s -> 10s (capped)
b = x.NewExponentialBackoff(1*time.Second, 10*time.Second)
// Fibonacci: 1s -> 1s -> 2s -> 3s -> 5s -> 8s -> 10s (capped)
b = x.NewFibonacciBackoff(1*time.Second, 10*time.Second)// Limit retries
b := x.WithMaxRetries(5, x.NewExponentialBackoff(100*time.Millisecond, 10*time.Second))
// Cap individual delay
b = x.WithCappedDuration(5*time.Second, b)
// Limit total retry time
b = x.WithMaxDuration(30*time.Second, b)
// Add jitter to prevent thundering herd
b = x.WithJitter(100*time.Millisecond, b)
b = x.WithJitterPercent(10, b) // +/- 10%backoff := x.NewBackOffWithJitter(100*time.Millisecond, 10*time.Second, 0.5)
delay := backoff.Get("operation-id")
backoff.Next("operation-id", time.Now())
backoff.Reset("operation-id")limiter := x.NewTokenBucketRateLimiter(10.0, 5)
if limiter.TryAccept() { /* process */ }
limiter.Accept() // blocks until availableInjectable clock for testing.
clock := x.RealClock{}
now := clock.Now()
clock.Sleep(time.Second)config := &x.TypedLazyConfig{
Name: "myconfig",
Type: "database",
Config: json.RawMessage(`{"host":"localhost"}`),
}
var dbConfig DatabaseConfig
config.Unmarshal(&dbConfig)original := map[string][]int{"a": {1, 2, 3}}
copied := x.DeepCopy(original)inContainer, err := x.IsInContainer(os.Getpid())err := x.GraceStart(func(stopCh x.GraceSignalChan) error {
<-stopCh
return nil
})
err := x.GraceRun(func() error {
return http.ListenAndServe(":8080", nil)
})home, err := x.HomeDir()
path, err := x.WithHomeDir("~/.config/app")writer := x.LineWriter(func(line []byte) error {
fmt.Println(string(line))
return nil
}, true)keyPEM, err := x.MakeEllipticPrivateKeyPEM()
key, err := x.ParsePrivateKeyPEM(pemData)pattern := x.Glob("*.txt")
if pattern.Match("readme.txt") { /* matched */ }selectors := x.Selectors{
{Key: ".Name", Operator: x.OperatorIn, Values: []string{"alice"}},
}
selectors.Init()
if selectors.Match(user) { /* matched */ }Operators: OperatorIn, OperatorNotIn, OperatorExists, OperatorNotExists, OperatorGt, OperatorLt, OperatorRange
Zero-allocation conversions (unsafe).
b := x.Str2Bytes("hello")
s := x.Bytes2Str(b)smaller := x.Min(int64(10), int64(20))
larger := x.Max(3.14, 2.71)Fluent conditional values.
result := x.V(config.Port).Or(8080).Value()
result := x.V(value).If(condition).Or(defaultValue).Value()Generic factory pattern.
f := factory.NewFactory[Plugin, Option]()
f.Register("example", creator)
plugin, err := f.Create(cfg)Shell execution with mvdan.cc/sh.
sh.Run("echo hello")
sh.Run("@script.sh")Deep merge maps/structs.
jsonmerge.Merge(&dst, src)HTTP utilities and API responses.
httputil.NewResponse(w).WithData(result).Flush()
httputil.CloneRequest(req)System service management (darwin/linux/windows).
svc, _ := service.New("myservice", "description")
svc.Install()
svc.Start()Semantic versioning.
info := version.Get()
v1, _ := version.NewSemver("1.2.3")Linux cgroup utilities.
import "go.zoe.im/x/cgroup/automaxprocs"
automaxprocs.Set()CLI builder with config support.
cmd := cli.New(cli.Name("myapp"), cli.WithConfig(&Config{}))
cmd.Run()Apache License 2.0