SkillAgentSearch skills...

Gust

A production-ready library that makes error handling, optional values, and iteration as beautiful and safe as in Rust.

Install / Use

/learn @andeya/Gust

README

<div align="center">

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 | 中文

</div>

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

✨ The Catch Pattern: gust's Secret Weapon

gust introduces the result.Ret + Unwrap + Catch pattern—a revolutionary way to handle errors in Go:

func fetchUserData(userID int) (r result.Result[string]) {
    defer r.Catch()  // One line handles ALL errors!
    user := result.Ret(db.GetUser(userID)).Unwrap()
    profile := result.Ret(api.GetProfile(user.Email)).Unwrap()
    return result.Ok(fmt.Sprintf("%s: %s", user.Name, profile.Bio))
}

One line (defer r.Catch()) eliminates all if err != nil checks. Errors automatically propagate via panic and are caught, converted to Result, and returned.

✨ Why gust?

| Traditional Go | With gust | |----------------|-----------| | ❌ 15+ lines of error checks | ✅ 3 lines with Catch pattern | | ❌ if err != nil everywhere | ✅ defer r.Catch() once | | ❌ 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 (with Catch Pattern)

package main

import (
    "fmt"
    "github.com/andeya/gust/result"
)

func main() {
    // Using Catch pattern - errors flow automatically!
    processValue := func(value int) (r result.Result[int]) {
        defer r.Catch()
        doubled := value * 2
        if doubled > 20 {
            return result.TryErr[int]("too large")
        }
        return result.Ok(doubled + 5)
    }

    res := processValue(10)
    if res.IsOk() {
        fmt.Println("Success:", res.Unwrap())
    } else {
        fmt.Println("Error:", res.UnwrapErr())
    }
}

Output: Success: 25


💡 The Problem gust Solves

Before: Traditional Go Code (15+ lines, 4 error checks)

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)
    }
    if profile == nil {
        return "", fmt.Errorf("profile not found")
    }
    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 Catch Pattern (8 lines, 0 error checks)

import "github.com/andeya/gust/result"

func fetchUserData(userID int) (r result.Result[string]) {
    defer r.Catch()  // One line handles ALL errors!
    user := result.Ret(db.GetUser(userID)).Unwrap()
    if user == nil || user.Email == "" {
        return result.TryErr[string]("invalid user")
    }
    profile := result.Ret(api.GetProfile(user.Email)).Unwrap()
    if profile == nil {
        return result.TryErr[string]("profile not found")
    }
    return result.Ok(fmt.Sprintf("%s: %s", user.Name, profile.Bio))
}

Benefits:

  • One line error handling - defer r.Catch() handles everything
  • Linear flow - Easy to read top-to-bottom
  • Automatic propagation - Errors stop execution automatically
  • Composable - Each step is independent and testable
  • Type-safe - Compiler enforces correct error handling
  • 70% less code - From 15+ lines to 8 lines

📚 Core Features

1. Result<T> - The Catch Pattern Revolution

The Catch pattern (result.Ret + Unwrap + Catch) is gust's most powerful feature:

import "github.com/andeya/gust/result"

// Before: Traditional Go (multiple error checks)
// func readConfig(filename string) (string, error) {
//     f, err := os.Open(filename)
//     if err != nil {
//         return "", err
//     }
//     defer f.Close()
//     data, err := io.ReadAll(f)
//     if err != nil {
//         return "", err
//     }
//     return string(data), nil
// }

// After: gust Catch pattern (linear flow, no error checks)
func readConfig(filename string) (r result.Result[string]) {
    defer r.Catch()  // One line handles ALL errors!
    data := result.Ret(os.ReadFile(filename)).Unwrap()
    return result.Ok(string(data))
}

Key Methods:

  • result.Ret(T, error) - Convert (T, error) to Result[T]
  • Unwrap() - Extract value (panics if error, caught by Catch)
  • defer r.Catch() - Catch all panics and convert to Result errors
  • Map - Transform value if Ok
  • AndThen - Chain operations returning Result
  • UnwrapOr - Extract safely with default (never panics)

Real-World Use Cases:

  • API call chains
  • Database operations
  • File I/O operations
  • Data validation pipelines

2. Option<T> - No More Nil Panics

Replace *T and (T, bool) with safe Option[T] that prevents nil pointer panics:

import "github.com/andeya/gust/option"

// Before: Traditional Go (nil checks everywhere)
// func divide(a, b float64) *float64 {
//     if b == 0 {
//         return nil
//     }
//     result := a / b
//     return &result
// }
// result := divide(10, 2)
// if result != nil {
//     fmt.Println(*result * 2)  // Risk of nil pointer panic
// }

// After: gust Option (type-safe, no nil panics)
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 }).
    UnwrapOr(0)  // Safe: never panics

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)

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"

// Before: Traditional Go (nested loops, manual error handling)
// func processNumbers(input []string) ([]int, error) {
//     var results []int
//     for _, s := range input {
//         n, err := strconv.Atoi(s)
//         if err != nil {
//             continue
//         }
//         if n > 0 {
//             results = append(results, n*2)
//         }
//     }
//     return results, nil
// }

// After: gust Iterator (declarative, type-safe, 70% less code)
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]

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 (Iterator + Result)

Before: Traditional Go (nested loops + error handling, 15+ lines)

func pro
View on GitHub
GitHub Stars126
CategoryDevelopment
Updated13d ago
Forks8

Languages

Go

Security Score

100/100

Audited on Mar 19, 2026

No findings