gust

module
v1.20.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 30, 2025 License: MIT

README ΒΆ

gust 🌬️

Write Go code that's as safe as Rust, as expressive as functional programming, and as fast as native Go.

A zero-dependency library that brings Rust's most powerful patterns to Go, eliminating error boilerplate, nil panics, and imperative loops.

GitHub release Go Version GoDoc CI Status Go Report Card Code Coverage License

English | δΈ­ζ–‡


🎯 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.

Performance

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.

Community
  • πŸ“– 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.


Made with ❀️ for the Go community

Inspired by Rust's Result, Option, and Iterator traits

⭐ Star us on GitHub β€’ πŸ“– Documentation β€’ πŸ› Report Bug β€’ πŸ’‘ Request Feature

Directories ΒΆ

Path Synopsis
Package bitset provides a thread-safe, efficient bit set implementation with comprehensive bit manipulation operations.
Package bitset provides a thread-safe, efficient bit set implementation with comprehensive bit manipulation operations.
Package constraints provides type constraints for generic programming.
Package constraints provides type constraints for generic programming.
Package conv provides generic functions for type conversion and value transformation.
Package conv provides generic functions for type conversion and value transformation.
Package dict provides generic functions for working with maps.
Package dict provides generic functions for working with maps.
Package digit provides generic functions for numeric digit operations.
Package digit provides generic functions for numeric digit operations.
Package encrypt provides a comprehensive collection of cryptographic functions with Rust-inspired error handling.
Package encrypt provides a comprehensive collection of cryptographic functions with Rust-inspired error handling.
Package errutil provides utilities for error handling and manipulation.
Package errutil provides utilities for error handling and manipulation.
internal
Package iterator provides a complete implementation of Rust's Iterator trait in Go.
Package iterator provides a complete implementation of Rust's Iterator trait in Go.
Package option provides helper functions for working with Option types.
Package option provides helper functions for working with Option types.
Package pair provides a generic Pair type for representing pairs of values.
Package pair provides a generic Pair type for representing pairs of values.
Package random provides secure random string generation with optional timestamp encoding.
Package random provides secure random string generation with optional timestamp encoding.
Package result provides helper functions for working with Result types.
Package result provides helper functions for working with Result types.
Package syncutil provides concurrent utilities for safe concurrent programming.
Package syncutil provides concurrent utilities for safe concurrent programming.
Package vec provides generic functions for working with slices and arrays.
Package vec provides generic functions for working with slices and arrays.
Package void provides a Void type for representing the absence of a value.
Package void provides a Void type for representing the absence of a value.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL