π― What is gust?
gust is a production-ready Go library that brings Rust's most powerful patterns to Go. It transforms how you write Go code by providing:
- Type-safe error handling with
Result[T] - eliminate if err != nil boilerplate
- Safe optional values with
Option[T] - no more nil pointer panics
- Declarative iteration with 60+ iterator methods - write data pipelines like Rust
With zero dependencies and full type safety, gust lets you write Go code that's safer, cleaner, and more expressiveβwithout sacrificing performance.
β¨ Why gust?
| Traditional Go |
With gust |
| β 15+ lines of error checks |
β
3 lines of chainable code |
β if err != nil everywhere |
β
Errors flow automatically |
| β Nil pointer panics |
β
Compile-time safety |
| β Imperative loops |
β
Declarative pipelines |
| β Hard to compose |
β
Elegant method chaining |
π Quick Start
go get github.com/andeya/gust
Your First gust Program
package main
import (
"fmt"
"github.com/andeya/gust/result"
)
func main() {
// Chain operations elegantly - errors flow automatically!
res := result.Ok(10).
Map(func(x int) int { return x * 2 }).
AndThen(func(x int) result.Result[int] {
if x > 20 {
return result.TryErr[int]("too large")
}
return result.Ok(x + 5)
})
fmt.Println(res.UnwrapOr(0)) // 25 (safe: returns 0 if error)
}
Output: 25
π‘ The Problem gust Solves
Before: Traditional Go Code
func fetchUserData(userID int) (string, error) {
user, err := db.GetUser(userID)
if err != nil {
return "", fmt.Errorf("db error: %w", err)
}
if user == nil {
return "", fmt.Errorf("user not found")
}
if user.Email == "" {
return "", fmt.Errorf("invalid user: no email")
}
profile, err := api.GetProfile(user.Email)
if err != nil {
return "", fmt.Errorf("api error: %w", err)
}
return fmt.Sprintf("%s: %s", user.Name, profile.Bio), nil
}
Problems:
- β 4 repetitive
if err != nil checks
- β 3 nested conditionals
- β Hard to test individual steps
- β Easy to forget error handling
- β 15 lines of boilerplate
After: With gust
import "github.com/andeya/gust/result"
func fetchUserData(userID int) result.Result[string] {
return result.Ret(db.GetUser(userID)).
AndThen(func(user *User) result.Result[string] {
if user == nil || user.Email == "" {
return result.TryErr[string]("invalid user")
}
return result.Ret(api.GetProfile(user.Email)).
Map(func(profile *Profile) string {
return fmt.Sprintf("%s: %s", user.Name, profile.Bio)
})
})
}
Benefits:
- β
Eliminates repetitive error checks - Errors flow naturally
- β
Linear flow - Easy to read top-to-bottom
- β
Automatic propagation - Errors stop the chain automatically
- β
Composable - Each step is independent and testable
- β
Type-safe - Compiler enforces correct error handling
π Core Features
1. Result - Type-Safe Error Handling
Replace (T, error) with chainable Result[T] that eliminates error boilerplate:
import "github.com/andeya/gust/result"
res := result.Ok(10).
Map(func(x int) int { return x * 2 }).
AndThen(func(x int) result.Result[int] {
if x > 15 {
return result.TryErr[int]("too large")
}
return result.Ok(x + 5)
}).
OrElse(func(err error) result.Result[int] {
return result.Ok(0) // Fallback value
})
fmt.Println(res.UnwrapOr(0)) // 25 (safe, never panics)
Key Methods:
Map - Transform value if Ok
AndThen - Chain operations returning Result
OrElse - Handle errors with fallback
UnwrapOr - Extract safely with default (never panics)
Unwrap - Extract value (β οΈ panics if error - use only after IsOk() check)
Real-World Use Cases:
- API call chains
- Database operations
- File I/O operations
- Data validation pipelines
2. Option - No More Nil Panics
Replace *T and (T, bool) with safe Option[T] that prevents nil pointer panics:
import "github.com/andeya/gust/option"
divide := func(a, b float64) option.Option[float64] {
if b == 0 {
return option.None[float64]()
}
return option.Some(a / b)
}
quotient := divide(10, 2).
Map(func(x float64) float64 { return x * 2 }).
Filter(func(x float64) bool { return x > 5 }).
UnwrapOr(0)
fmt.Println(quotient) // 10
Key Methods:
Map - Transform value if Some
AndThen - Chain operations returning Option
Filter - Conditionally filter values
UnwrapOr - Extract safely with default (never panics)
Unwrap - Extract value (β οΈ panics if None - use only after IsSome() check)
Real-World Use Cases:
- Configuration reading
- Optional function parameters
- Map lookups
- JSON unmarshaling
3. Iterator - Rust-like Iteration
Full Rust Iterator trait implementation with 60+ methods for declarative data processing:
import "github.com/andeya/gust/iterator"
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
sum := iterator.FromSlice(numbers).
Filter(func(x int) bool { return x%2 == 0 }).
Map(func(x int) int { return x * x }).
Take(3).
Fold(0, func(acc, x int) int { return acc + x })
fmt.Println(sum) // 56 (4 + 16 + 36)
Highlights:
- π 60+ methods from Rust's Iterator trait
- π Lazy evaluation - Computations happen on-demand
- π Method chaining - Compose complex operations elegantly
- π Go 1.24+ integration - Works with standard
iter.Seq[T]
- π― Type-safe - Compile-time guarantees
- β‘ Zero-cost abstractions - No performance overhead
Method Categories:
- Constructors:
FromSlice, FromRange, FromFunc, Empty, Once, Repeat
- BitSet Iterators:
FromBitSet, FromBitSetOnes, FromBitSetZeros
- Go Integration:
FromSeq, Seq, Pull (Go 1.24+ standard iterators)
- Basic Adapters:
Map, Filter, Chain, Zip, Enumerate
- Filtering:
Skip, Take, StepBy, SkipWhile, TakeWhile
- Transforming:
MapWhile, Scan, FlatMap, Flatten
- Chunking:
MapWindows, ArrayChunks, ChunkBy
- Consumers:
Collect, Fold, Reduce, Count, Sum, Product, Partition
- Search:
Find, FindMap, Position, All, Any
- Min/Max:
Max, Min, MaxBy, MinBy, MaxByKey, MinByKey
- Double-Ended:
NextBack, Rfold, Rfind, NthBack
π Real-World Examples
Example 1: Data Processing Pipeline
Parse, validate, transform, and limit user input in a single chain:
import (
"github.com/andeya/gust/iterator"
"github.com/andeya/gust/result"
"strconv"
)
input := []string{"10", "20", "invalid", "30", "0", "40"}
results := iterator.FilterMap(
iterator.RetMap(iterator.FromSlice(input), strconv.Atoi),
result.Result[int].Ok,
).
Filter(func(x int) bool { return x > 0 }).
Map(func(x int) int { return x * 2 }).
Take(3).
Collect()
fmt.Println(results) // [20 40 60]
Example 2: API Call Chain with Error Handling
Handle multiple API calls with automatic error propagation:
import "github.com/andeya/gust/result"
func fetchUserProfile(userID int) result.Result[string] {
return result.Ret(db.GetUser(userID)).
AndThen(func(user *User) result.Result[string] {
if user == nil || user.Email == "" {
return result.TryErr[string]("invalid user")
}
return result.Ret(api.GetProfile(user.Email)).
Map(func(profile *Profile) string {
return fmt.Sprintf("%s: %s", user.Name, profile.Bio)
})
})
}
// Usage
profileRes := fetchUserProfile(123)
if profileRes.IsOk() {
fmt.Println(profileRes.Unwrap())
} else {
fmt.Println("Error:", profileRes.UnwrapErr())
}
Example 3: Configuration Management
Safely read and validate configuration with Option:
import (
"github.com/andeya/gust/option"
"os"
"strconv"
)
type Config struct {
APIKey option.Option[string]
Port option.Option[int]
}
func loadConfig() Config {
apiKeyEnv := os.Getenv("API_KEY")
var apiKeyPtr *string
if apiKeyEnv != "" {
apiKeyPtr = &apiKeyEnv
}
return Config{
APIKey: option.ElemOpt(apiKeyPtr),
Port: option.RetOpt(strconv.Atoi(os.Getenv("PORT"))),
}
}
config := loadConfig()
port := config.Port.UnwrapOr(8080) // Default to 8080 if not set
apiKey := config.APIKey.UnwrapOr("") // Default to empty string
Example 4: BitSet with Iterators
Process bit sets using iterator methods:
import (
"github.com/andeya/gust/bitset"
"github.com/andeya/gust/iterator"
)
bs := bitset.New()
bs.Set(0, true).Unwrap()
bs.Set(5, true).Unwrap()
// Get all set bits using iterator
setBits := iterator.FromBitSetOnes(bs).Collect() // [0 5]
// Bitwise operations
bs1 := bitset.NewFromString("c0", bitset.EncodingHex).Unwrap()
bs2 := bitset.NewFromString("30", bitset.EncodingHex).Unwrap()
or := bs1.Or(bs2)
// Encoding/decoding (Base64URL by default)
encoded := bs.String()
decoded := bitset.NewFromBase64URL(encoded).Unwrap()
π¦ Complete Package Ecosystem
gust provides a comprehensive set of utility packages for common Go tasks:
| Package |
Description |
Key Features |
gust/result |
Type-safe error handling |
Result[T], Map, AndThen, OrElse |
gust/option |
Safe optional values |
Option[T], Map, Filter, AndThen |
gust/iterator |
Rust-like iteration |
60+ methods, lazy evaluation, method chaining |
gust/dict |
Generic map utilities |
Filter, Map, Keys, Values, Get |
gust/vec |
Generic slice utilities |
MapAlone, Get, Copy, Dict |
gust/conv |
Type-safe conversions |
BytesToString, StringToReadonlyBytes, case conversion, JSON quoting |
gust/digit |
Number conversions |
Base 2-62 conversion, FormatByDict, ParseByDict |
gust/random |
Secure random strings |
Base36/Base62 encoding, timestamp embedding |
gust/encrypt |
Cryptographic functions |
MD5, SHA series, FNV, CRC, Adler-32, AES encryption |
gust/bitset |
Thread-safe bit sets |
Bitwise ops, iterator integration, multiple encodings |
gust/syncutil |
Concurrent utilities |
SyncMap, Lazy, mutex wrappers |
gust/errutil |
Error utilities |
Stack traces, panic recovery, ErrBox |
gust/constraints |
Type constraints |
Ordering, Numeric, Digit |
π― Why Choose gust?
Zero Dependencies
gust has zero external dependencies. It only uses Go's standard library, keeping your project lean and secure.
Production Ready
- β
Comprehensive test coverage
- β
Full documentation with examples
- β
Battle-tested in production
- β
Active maintenance and support
Type Safety
All operations are type-safe with compile-time guarantees. The Go compiler enforces correct usage.
gust uses zero-cost abstractions. There's no runtime overhead compared to traditional Go code.
Go 1.24+ Integration
Seamlessly works with Go 1.24+'s standard iter.Seq[T] iterators, bridging the gap between gust and standard Go.
- π Complete API documentation
- π‘ Rich examples for every feature
- π Active issue tracking
- π¬ Community discussions
π Resources
π Requirements
- Go 1.24+ (required for generics and standard iterator support)
π€ Contributing
We welcome contributions! Whether you're:
- π Reporting bugs - Help us improve
- π‘ Suggesting features - Share your ideas
- π Improving docs - Make documentation better
- π§ Submitting PRs - Contribute code improvements
Every contribution makes gust better!
Development Setup
# Clone the repository
git clone https://github.com/andeya/gust.git
cd gust
# Run tests
go test ./...
# Run tests with coverage
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
π License
This project is licensed under the MIT License - see the LICENSE file for details.