Skip to content

seyallius/goxide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

33 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Goxide - Rust patterns in GO?

GoDoc Go Version License Status

goxide logo goxide logo 2

A comprehensive Go utilities library inspired by Rust's safety and expressiveness, providing robust error handling, reflection utilities, and functional programming patterns.

πŸ“¦ Packages Overview

Rust-Inspired Patterns (rusty package)

  • result: Rust-like Result type with Try/Catch patterns (equivalent to Rust's ? operator)
  • option: Optional value handling without nil panics
  • chain: Fluent method chaining for Result and Option types
  • types: Generic functional programming helpers

πŸš€ Quick Start

Installation

go get github.com/seyedali-dev/goxide

Basic Usage

import (
    "github.com/seyedali-dev/goxide/rusty/result"
    "github.com/seyedali-dev/goxide/rusty/option"
    "github.com/seyedali-dev/goxide/rusty/chain"
    "github.com/seyedali-dev/goxide/reflect"
)

// Result pattern for error handling (Rust's ? equivalent)
func GetUser(id int) (res result.Result[User]) {
    defer result.Catch(&res)
    
    user := db.FindUser(id).BubbleUp() // Early return on error
    profile := db.FindProfile(user.ID).BubbleUp() // ? - bubbleup error and return
    
    return result.Ok(profile)
}

// Option pattern for optional values
func GetUserName(userID int) string {
    userOpt := cache.GetUser(userID)
    return userOpt.UnwrapOr("Guest")
}

// Chain pattern for fluent operations
func ProcessUser(userID int) result.Result[string] {
    return chain.Chain(findUser(userID)).
        Map(func(u User) string { return u.Name }).
        AndThen(validateName).
        Unwrap()
}

// Reflection utilities
func GetStructTags(user User) []string {
    return reflect.FieldTagKeys(user, "Name")
}

🎯 Key Features

πŸ”’ Type Safety

  • Compiler-enforced error handling
  • No nil pointer dereferences
  • Explicit optional values

πŸ› οΈ Error Handling

  • Rust-like Result type with BubbleUp() for early returns (equivalent to Rust's ? operator)
  • Error recovery with CatchWith and Fallback
  • Functional composition with Map, AndThen, FlatMap

πŸ” Reflection Made Safe

  • Type-safe struct operations
  • Compile-time field validation
  • Struct tag parsing and validation

πŸ”— Fluent APIs

  • Method chaining for complex operations
  • Pipeline-style programming with the chain package
  • Readable sequential operations

πŸ“š Package Details

Rust-inspired error handling with early returns and error recovery patterns.

Key Features:

  • BubbleUp() method equivalent to Rust's ? operator
  • Error-specific recovery with CatchWith
  • Functional composition with Map and AndThen
  • Multi-error combination with Map2 and Map3

Example:

func ProcessOrder(orderID int) (res result.Result[Receipt]) {
    defer result.Catch(&res)
    
    order := FindOrder(orderID).BubbleUp()
    payment := ProcessPayment(order).BubbleUp()
    receipt := GenerateReceipt(payment).BubbleUp()
    
    return result.Ok(receipt)
}

Safe optional value handling without nil pointer panics.

Key Features:

  • Explicit Some/None semantics
  • Safe value extraction with fallbacks
  • Functional transformation with Map and FlatMap
  • Type-safe optional operations

Example:

func GetUserEmail(userID int) option.Option[string] {
    userOpt := cache.GetUser(userID)
    return option.Map(userOpt, func(u User) string {
        return u.Email
    })
}

Chain Package (work in progress)

Fluent method chaining for Result and Option types.

Key Features:

  • Pipeline-style operation sequencing
  • Type-safe transformation chains
  • No nested Map/AndThen calls
  • Better readability for complex operations

Example:

chain.Chain(findUser(123)).
    Map(func(u User) string { return u.Name }).
    AndThen(validateName)

Generic functional programming helpers.

Key Features:

  • Identity function and constant generators
  • Function composition utilities
  • Higher-order function support
  • Integration with Result and Option

Example:

// Function composition
process := types.Compose(strings.TrimSpace, strings.ToUpper)
result := process("  hello  ") // "HELLO"

πŸ—οΈ Architecture Principles

1. Explicit Over Implicit

  • No hidden nil checks
  • Clear error propagation
  • Explicit optional values

2. Type Safety First

  • Compiler-enforced patterns
  • Generic type constraints
  • Runtime safety guarantees

3. Multiple Patterns

  • Choose between traditional, functional, or early-return styles
  • Gradual adoption path
  • No lock-in to single approach

4. Performance Conscious

  • Zero allocations in happy paths
  • Minimal overhead over traditional patterns
  • Benchmark-driven optimizations

πŸ“– Examples

Comprehensive examples are available in the examples package:

You can also find more detailed explanation in each sub-packages e.g., Result Package, Option Package, Chain Package, Types Package (some might not have as the docstring explanation suffices).

πŸ”§ Migration Guide

From Traditional Go

Before:

func GetUserData(id int) (UserData, error) {
    user, err := db.FindUser(id)
    if err != nil {
        return UserData{}, err
    }
    
    profile, err := db.FindProfile(user.ID)
    if err != nil {
        return UserData{}, err
    }
    
    return ProcessData(user, profile), nil
}

After (with Try pattern):

func GetUserData(id int) (res result.Result[UserData]) {
    defer result.Catch(&res)
    
    user := db.FindUser(id).BubbleUp()
    profile := db.FindProfile(user.ID).BubbleUp()
    
    return result.Ok(ProcessData(user, profile))
}

After (with Chain pattern):

func GetUserData(id int) result.Result[UserData] {
    return chain.Chain(db.FindUser(id)).
        AndThen(func(user User) result.Result[Profile] {
            return db.FindProfile(user.ID)
        }).
        Map(func(profile Profile) UserData {
            return ProcessData(user, profile)
        }).
        Unwrap()
}

Gradual Adoption

Wrap existing functions without changing signatures:

var findUser = result.WrapFunc1(db.FindUser)
var loadConfig = result.WrapFunc(config.Load)

// Use new patterns incrementally
func MixedUsage(id int) (User, error) {
    var user User
    var err error
    defer result.CatchErr(&user, &err)
    
    config := loadConfig().BubbleUp()
    user = findUser(id).BubbleUp()
    
    return user, nil
}

πŸ“Š Performance

Benchmarks show minimal overhead:

Traditional error handling:   100 ns/op
Result with Try/Catch:        150 ns/op (+50%)
Result with AndThen:          110 ns/op (+10%)
Chain operations:             115 ns/op (+15%)
Option operations:            5-10 ns/op

Recommendations:

  • Use BubbleUp() for business logic where clarity matters
  • Use Chain for complex operation sequences
  • Use traditional patterns in performance-critical loops
  • The readability benefit usually outweighs the small cost

🀝 Contributing

You're welcome for contributions! Please see our Contributing Guide for details.

Development Setup

git clone https://github.com/seyedali-dev/goxide
cd gopherbox
go test ./...

Running Tests

# Run all tests
go test ./...

# Run with coverage
go test -cover ./...

# Run benchmarks
go test -bench=. ./...

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

Portions of this software are derived from work licensed under the Apache License 2.0 and MIT License.
See THIRD_PARTY_LICENSES for the full license text.

πŸ™ Acknowledgments

Inspired by:

  • Rust's Result<T, E> and Option<T> types with ? operator
  • Functional programming patterns and composition
  • Go's simplicity and pragmatism
  • The Go community's best practices

πŸ“ž Support

πŸš€ Roadmap

  • v.15.0: Improve the result to avoid memory allocation
  • v1.0.0: Enhanced chaining
  • v1.1.0: Enhanced collection utilities
  • v1.2.0: Async/await patterns for Go
  • v1.3.0: Database integration helpers

Built with ❀️ for the Go community

Making Go development safer, more expressive, and more enjoyable

About

Rust oxidization in Go?

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages