gust

package module
v1.12.0 Latest Latest
Warning

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

Go to latest
Published: Dec 27, 2025 License: MIT Imports: 12 Imported by: 0

README

gust 🌬️

tag Go Version GoDoc Build Status Go report Coverage License

Bring Rust's elegance to Go - A powerful library that makes error handling, optional values, and iteration as beautiful and safe as in Rust.

🎯 Zero dependencies • 🚀 Production ready • 📚 Well documented • ✨ Type-safe

Languages: English | 中文

✨ Why gust?

Tired of writing if err != nil everywhere? Frustrated with nil pointer panics? Want Rust-like iterator chains in Go?

gust brings Rust's best patterns to Go, making your code:

  • 🛡️ Safer - No more nil pointer panics
  • 🎯 Cleaner - Chain operations elegantly
  • 🚀 More Expressive - Write what you mean, not boilerplate
From Imperative to Declarative

gust helps you shift from imperative (focusing on how) to declarative (focusing on what) programming:

Declarative vs Imperative

With gust, you describe what you want to achieve, not how to achieve it step-by-step. This makes your code more readable, maintainable, and less error-prone.

Before gust (Traditional Go)
func fetchUserData(userID int) (string, error) {
    // Step 1: Fetch from database
    user, err := db.GetUser(userID)
    if err != nil {
        return "", fmt.Errorf("db error: %w", err)
    }
    
    // Step 2: Validate user
    if user == nil {
        return "", fmt.Errorf("user not found")
    }
    if user.Email == "" {
        return "", fmt.Errorf("invalid user: no email")
    }
    
    // Step 3: Fetch profile
    profile, err := api.GetProfile(user.Email)
    if err != nil {
        return "", fmt.Errorf("api error: %w", err)
    }
    
    // Step 4: Format result
    result := fmt.Sprintf("%s: %s", user.Name, profile.Bio)
    return result, nil
}
After gust (Elegant & Safe)
import "github.com/andeya/gust"
import "github.com/andeya/gust/ret"

func fetchUserData(userID int) gust.Result[string] {
    return ret.AndThen(gust.Ret(getUser(userID)), func(user *User) gust.Result[string] {
        if user == nil || user.Email == "" {
            return gust.Err[string]("invalid user")
        }
        return ret.Map(gust.Ret(getProfile(user.Email)), func(profile *Profile) string {
            return fmt.Sprintf("%s: %s", user.Name, profile.Bio)
        })
    })
}

// See ExampleResult_fetchUserData in examples/ for a complete runnable example

What changed?

  • No error boilerplate - Errors flow naturally through the chain
  • No nested if-else - Linear flow, easy to read
  • Automatic propagation - Errors stop the chain automatically
  • Composable - Each step is independent and testable
  • Type-safe - Compiler enforces correct error handling

🚀 Quick Start

go get github.com/andeya/gust

📚 Core Features

1. Result - Elegant Error Handling

Replace (T, error) with chainable Result[T]:

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

// Chain operations that can fail
result := gust.Ok(10).
    Map(func(x int) int { return x * 2 }).
    AndThen(func(x int) gust.Result[int] {
        if x > 15 {
            return gust.Err[int]("too large")
        }
        return gust.Ok(x + 5)
    }).
    OrElse(func(err error) gust.Result[int] {
        fmt.Println("Error handled:", err)
        return gust.Ok(0) // Fallback
    })

fmt.Println("Final value:", result.Unwrap())
// Output: Error handled: too large
// Final value: 0

Key Benefits:

  • ✅ No more if err != nil boilerplate
  • ✅ Automatic error propagation
  • ✅ Chain multiple operations elegantly
  • ✅ Type-safe error handling
2. Option - No More Nil Panics

Replace *T and (T, bool) with safe Option[T]:

// Safe division without nil checks
divide := func(a, b float64) gust.Option[float64] {
    if b == 0 {
        return gust.None[float64]()
    }
    return gust.Some(a / b)
}

result := divide(10, 2).
    Map(func(x float64) float64 { return x * 2 }).
    UnwrapOr(0)

fmt.Println(result) // 10

Key Benefits:

  • ✅ Eliminates nil pointer panics
  • ✅ Explicit optional values
  • ✅ Chain operations safely
  • ✅ Compiler-enforced safety
3. Iterator - Rust-like Iteration in Go

Full Rust Iterator trait implementation with method chaining:

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

numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

sum := iter.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 int, x int) int {
        return acc + x
    })

fmt.Println(sum) // 56 (4 + 16 + 36)

Available Methods:

  • Constructors: FromSlice(), FromElements(), FromRange(), FromFunc(), FromIterable(), Empty(), Once(), Repeat() - Create iterators from various sources
  • BitSet Iterators: FromBitSet(), FromBitSetOnes(), FromBitSetZeros(), FromBitSetBytes(), FromBitSetBytesOnes(), FromBitSetBytesZeros() - Iterate over bits in bit sets or byte slices
  • Go Integration: FromSeq(), FromSeq2(), FromPull(), FromPull2() - Convert from Go's standard iterators; Seq(), Seq2(), Pull(), Pull2() - Convert to Go's standard iterators
  • Adapters: Map, Filter, Chain, Zip, Enumerate, Skip, Take, StepBy, FlatMap, Flatten
  • Consumers: Fold, Reduce, Collect, Count, All, Any, Find, Sum, Product, Partition
  • Advanced: Scan, Intersperse, Peekable, ArrayChunks, FindMap, MapWhile
  • Double-Ended: NextBack, Rfold, TryRfold, Rfind
  • And 60+ more methods from Rust's Iterator trait!

Note: For type-changing operations (e.g., Map from string to int), use the function-style API:

iter.Map(iter.FromSlice(strings), func(s string) int { return len(s) })

For same-type operations, you can use method chaining:

iter.FromSlice(numbers).Filter(func(x int) bool { return x > 0 }).Map(func(x int) int { return x * 2 })

Key Benefits:

  • ✅ Rust-like method chaining
  • ✅ Lazy evaluation
  • ✅ Type-safe transformations
  • ✅ Zero-copy where possible
Iterator Constructors

Create iterators from various sources:

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

// From slice
iter1 := iter.FromSlice([]int{1, 2, 3})

// From individual elements
iter2 := iter.FromElements(1, 2, 3)

// From range [start, end)
iter3 := iter.FromRange(0, 5) // 0, 1, 2, 3, 4

// From function
count := 0
iter4 := iter.FromFunc(func() gust.Option[int] {
    if count < 3 {
        count++
        return gust.Some(count)
    }
    return gust.None[int]()
})

// Empty iterator
iter5 := iter.Empty[int]()

// Single value
iter6 := iter.Once(42)

// Infinite repeat
iter7 := iter.Repeat("hello") // "hello", "hello", "hello", ...
Go Standard Iterator Integration

gust iterators seamlessly integrate with Go 1.23+ standard iterators:

Convert gust Iterator to Go's iter.Seq[T]:

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

numbers := []int{1, 2, 3, 4, 5}
gustIter := iter.FromSlice(numbers).Filter(func(x int) bool { return x%2 == 0 })

// Use in Go's standard for-range loop
for v := range gustIter.Seq() {
    fmt.Println(v) // prints 2, 4
}

Convert Go's iter.Seq[T] to gust Iterator:

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

// Create a Go standard iterator sequence
goSeq := func(yield func(int) bool) {
    for i := 0; i < 5; i++ {
        if !yield(i) {
            return
        }
    }
}

// Convert to gust Iterator and use gust methods
gustIter, deferStop := iter.FromSeq(goSeq)
defer deferStop()
result := gustIter.Map(func(x int) int { return x * 2 }).Collect()
fmt.Println(result) // [0 2 4 6 8]
4. Double-Ended Iterator

Iterate from both ends:

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

numbers := []int{1, 2, 3, 4, 5}
deIter := iter.FromSlice(numbers).MustToDoubleEnded()

// Iterate from front
if val := deIter.Next(); val.IsSome() {
    fmt.Println("Front:", val.Unwrap()) // Front: 1
}

// Iterate from back
if val := deIter.NextBack(); val.IsSome() {
    fmt.Println("Back:", val.Unwrap()) // Back: 5
}

📖 Examples

Parse and Filter with Error Handling
import "github.com/andeya/gust"
import "github.com/andeya/gust/iter"
import "strconv"

// Parse strings to integers, automatically filtering out errors
numbers := []string{"1", "2", "three", "4", "five"}

results := iter.FilterMap(
    iter.RetMap(iter.FromSlice(numbers), strconv.Atoi),
    gust.Result[int].Ok,
).
    Collect()

fmt.Println("Parsed numbers:", results)
// Output: Parsed numbers: [1 2 4]
Real-World Data Pipeline
// Process user input: parse, validate, transform, limit
input := []string{"10", "20", "invalid", "30", "0", "40"}

results := iter.FilterMap(
    iter.RetMap(iter.FromSlice(input), strconv.Atoi),
    gust.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]
Option Chain Operations
// Chain operations on optional values with filtering
result := gust.Some(5).
    Map(func(x int) int { return x * 2 }).
    Filter(func(x int) bool { return x > 8 }).
    XMap(func(x int) any {
        return fmt.Sprintf("Value: %d", x)
    }).
    UnwrapOr("No value")

fmt.Println(result) // "Value: 10"
Partition Data
// Split numbers into evens and odds
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

evens, odds := iter.FromSlice(numbers).
    Partition(func(x int) bool { return x%2 == 0 })

fmt.Println("Evens:", evens) // [2 4 6 8 10]
fmt.Println("Odds:", odds)   // [1 3 5 7 9]
BitSet Iteration

Iterate over bits in bit sets or byte slices with full iterator support:

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

// Iterate over bits in a byte slice
bytes := []byte{0b10101010, 0b11001100}

// Get all set bit offsets
setBits := iter.FromBitSetBytesOnes(bytes).
    Filter(func(offset int) bool { return offset > 5 }).
    Collect()
fmt.Println(setBits) // [6 8 9 12 13]

// Count set bits
count := iter.FromBitSetBytesOnes(bytes).Count()
fmt.Println(count) // 8

// Sum of offsets of set bits
sum := iter.FromBitSetBytesOnes(bytes).
    Fold(0, func(acc, offset int) int { return acc + offset })
fmt.Println(sum) // 54 (0+2+4+6+8+9+12+13)

// Works with any BitSetLike implementation
type MyBitSet struct {
    bits []byte
}

func (b *MyBitSet) Size() int { return len(b.bits) * 8 }
func (b *MyBitSet) Get(offset int) bool {
    if offset < 0 || offset >= b.Size() {
        return false
    }
    byteIdx := offset / 8
    bitIdx := offset % 8
    return (b.bits[byteIdx] & (1 << (7 - bitIdx))) != 0
}

bitset := &MyBitSet{bits: []byte{0b10101010}}
ones := iter.FromBitSetOnes(bitset).Collect()
fmt.Println(ones) // [0 2 4 6]

📦 Additional Packages

gust provides several utility packages to extend its functionality:

  • gust/dict - Generic map utilities (Filter, Map, Keys, Values, etc.)
  • gust/vec - Generic slice utilities
  • gust/valconv - Type-safe value conversion
  • gust/digit - Number conversion utilities
  • gust/opt - Helper functions for Option[T] (Map, AndThen, Zip, Unzip, Assert, etc.)
  • gust/ret - Helper functions for Result[T] (Map, AndThen, Assert, Flatten, etc.)
  • gust/iter - Rust-like iterator implementation (see Iterator section above)
Quick Examples

Dict utilities:

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

m := map[string]int{"a": 1, "b": 2, "c": 3}
value := dict.Get(m, "b").UnwrapOr(0) // 2
filtered := dict.Filter(m, func(k string, v int) bool { return v > 1 })

Vec utilities:

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

numbers := []int{1, 2, 3, 4, 5}
doubled := vec.MapAlone(numbers, func(x int) int { return x * 2 })

Opt utilities:

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

some := gust.Some(5)
doubled := opt.Map(some, func(x int) int { return x * 2 })

Ret utilities:

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

result := gust.Ok(10)
doubled := ret.Map(result, func(x int) int { return x * 2 })

For more details, see the full documentation and examples.

Detailed Examples
Dict Utilities
import "github.com/andeya/gust/dict"

m := map[string]int{"a": 1, "b": 2, "c": 3}

// Get with Option
value := dict.Get(m, "b")
fmt.Println(value.UnwrapOr(0)) // 2

// Filter map
filtered := dict.Filter(m, func(k string, v int) bool {
    return v > 1
})
fmt.Println(filtered) // map[b:2 c:3]

// Map values
mapped := dict.MapValue(m, func(k string, v int) int {
    return v * 2
})
fmt.Println(mapped) // map[a:2 b:4 c:6]
Vec Utilities
import "github.com/andeya/gust/vec"

numbers := []int{1, 2, 3, 4, 5}
doubled := vec.MapAlone(numbers, func(x int) int { return x * 2 })
fmt.Println(doubled) // [2 4 6 8 10]
Opt Utilities
import "github.com/andeya/gust/opt"

some := gust.Some(5)
doubled := opt.Map(some, func(x int) int { return x * 2 })
zipped := opt.Zip(gust.Some(1), gust.Some("hello"))
Ret Utilities
import "github.com/andeya/gust/ret"

result := gust.Ok(10)
doubled := ret.Map(result, func(x int) int { return x * 2 })
chained := ret.AndThen(gust.Ok(5), func(x int) gust.Result[int] {
    return gust.Ok(x * 2)
})

🔗 Resources

📋 Requirements

Requires Go 1.23+ (for generics and standard iterator support)

🤝 Contributing

Contributions are welcome! Whether it's:

  • 🐛 Reporting bugs
  • 💡 Suggesting new features
  • 📝 Improving documentation
  • 🔧 Submitting pull requests

Every contribution makes gust better! Please feel free to submit a Pull Request or open an issue.

📄 License

This project is licensed under the MIT License.


Made with ❤️ for the Go community

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

Documentation

Overview

Package gust provides Rust-inspired error handling, optional values, and iteration utilities for Go. This file contains numeric type constraints for generic programming.

Package gust provides Rust-inspired error handling, optional values, and iteration utilities for Go. This file contains ordering types and comparison utilities.

Package gust provides Rust-inspired error handling, optional values, and iteration utilities for Go. This file contains common types and interfaces used throughout the package.

Package gust provides Rust-inspired error handling, optional values, and iteration utilities for Go. This file contains the Void type for representing the absence of a value.

Index

Examples

Constants

View Source
const ErrLazyValueWithoutInit = "*gust.LazyValue[T]: onceInit function is nil"

Variables

This section is empty.

Functions

func ToError added in v1.11.0

func ToError(r VoidResult) error

ToError converts VoidResult to a standard Go error. Returns nil if IsOk() is true, otherwise returns the error.

Example:

```go
var result gust.VoidResult = gust.RetVoid(err)
if err := gust.ToError(result); err != nil {
	return err
}
```

func UnwrapErrOr added in v1.11.0

func UnwrapErrOr(r VoidResult, def error) error

UnwrapErrOr returns the contained error value or a provided default for VoidResult.

Example:

```go
var result gust.VoidResult = gust.RetVoid(err)
err := gust.UnwrapErrOr(result, errors.New("default error"))
```

Types

type AtomicValue added in v1.4.0

type AtomicValue[T any] struct {
	// contains filtered or unexported fields
}

AtomicValue is a better generic-type wrapper for `atomic.Value`. A AtomicValue provides an atomic load and store of a consistently typed value. The zero value for a AtomicValue returns nil from Load. Once Store has been called, a AtomicValue must not be copied.

A AtomicValue must not be copied after first use.

func (*AtomicValue[T]) CompareAndSwap added in v1.4.0

func (v *AtomicValue[T]) CompareAndSwap(old T, new T) (swapped bool)

CompareAndSwap executes the compare-and-swap operation for the AtomicValue.

All calls to CompareAndSwap for a given AtomicValue must use values of the same concrete type. CompareAndSwap of an inconsistent type panics, as does CompareAndSwap(old, nil).

func (*AtomicValue[T]) Load added in v1.4.0

func (v *AtomicValue[T]) Load() (val Option[T])

Load returns the value set by the most recent Store. It returns None if there has been no call to Store for this AtomicValue.

func (*AtomicValue[T]) Store added in v1.4.0

func (v *AtomicValue[T]) Store(val T)

Store sets the value of the AtomicValue to x. All calls to Store for a given AtomicValue must use values of the same concrete type. Store of an inconsistent type panics, as does Store(nil).

func (*AtomicValue[T]) Swap added in v1.4.0

func (v *AtomicValue[T]) Swap(new T) (old Option[T])

Swap stores new into AtomicValue and returns the previous value. It returns None if the AtomicValue is empty.

All calls to Swap for a given AtomicValue must use values of the same concrete type. Swap of an inconsistent type panics, as does Swap(nil).

type DictEntry added in v1.4.3

type DictEntry[K comparable, V any] struct {
	Key   K
	Value V
}

DictEntry is a key-value entry of map.

func (DictEntry[K, V]) Split added in v1.9.1

func (d DictEntry[K, V]) Split() (K, V)

Split splits the dictionary entry into its two components.

type Digit added in v1.1.2

type Digit interface {
	Integer | ~float32 | ~float64
}

Digit represents numeric types including integers and floating-point numbers.

type DoubleEndedIterable added in v1.7.0

type DoubleEndedIterable[T any] interface {
	Iterable[T]
	SizeIterable[T]
	NextBack() Option[T]
}

DoubleEndedIterable represents an iterable that can be iterated from both ends.

type ErrBox added in v1.2.2

type ErrBox struct {
	// contains filtered or unexported fields
}

ErrBox is a wrapper for any error type. Use ToError() method to convert to error interface, or access ErrBox through Result.Err().

func BoxErr added in v1.11.0

func BoxErr(val any) *ErrBox

BoxErr wraps any error type into ErrBox.

func (*ErrBox) As added in v1.2.2

func (e *ErrBox) As(target any) bool

As finds the first error in err's chain that matches target, and if so, sets target to that error value and returns true. Otherwise, it returns false.

func (*ErrBox) GoString added in v1.11.0

func (e *ErrBox) GoString() string

GoString returns the Go-syntax representation. This implements the fmt.GoStringer interface.

func (*ErrBox) Is added in v1.2.2

func (e *ErrBox) Is(target error) bool

Is reports whether any error in err's chain matches target.

func (*ErrBox) IsEmpty added in v1.11.0

func (e *ErrBox) IsEmpty() bool

IsEmpty returns true if ErrBox is empty (nil receiver or nil val).

func (*ErrBox) String added in v1.11.0

func (e *ErrBox) String() string

String returns the string representation. This implements the fmt.Stringer interface.

func (*ErrBox) ToError added in v1.11.0

func (e *ErrBox) ToError() error

ToError converts ErrBox to error interface. Returns nil if the receiver is nil or val is nil. Returns a pointer to innerErrBox which implements the error interface.

Example:

```go
var eb gust.ErrBox = gust.BoxErr(errors.New("test"))
var err error = eb.ToError() // err is *innerErrBox implementing error
```

func (*ErrBox) Unwrap added in v1.2.2

func (e *ErrBox) Unwrap() error

Unwrap returns the inner error.

func (*ErrBox) Value added in v1.2.2

func (e *ErrBox) Value() any

Value returns the inner value.

func (*ErrBox) ValueOrDefault added in v1.11.0

func (e *ErrBox) ValueOrDefault() any

ValueOrDefault returns the inner value, or nil if ErrBox is nil or val is nil. This is useful when you want to safely extract a typed value from ErrBox.

type Frame added in v1.12.0

type Frame uintptr

Frame represents a program counter inside a stack frame. For historical reasons if Frame is interpreted as a uintptr its value represents the program counter + 1.

func (Frame) Format added in v1.12.0

func (f Frame) Format(s fmt.State, verb rune)

Format formats the frame according to the fmt.Formatter interface.

%s    source file
%d    source line
%n    function name
%v    equivalent to %s:%d

Format accepts flags that alter the printing of some verbs, as follows:

%+s   function name and path of source file relative to the compile time
      GOPATH separated by \n\t (<funcname>\n\t<path>)
%+v   equivalent to %+s:%d

func (Frame) MarshalText added in v1.12.0

func (f Frame) MarshalText() ([]byte, error)

MarshalText formats a stacktrace Frame as a text string. The output is the same as that of fmt.Sprintf("%+v", f), but without newlines or tabs.

type Integer added in v1.1.2

type Integer interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
}

Integer represents integer types including type aliases.

type Iterable added in v0.7.0

type Iterable[T any] interface {
	Next() Option[T]
}

Iterable represents a sequence of values that can be iterated over.

type IterableCount added in v0.7.0

type IterableCount interface {
	Count() uint
}

IterableCount represents an iterable that can count its elements.

type IterableSizeHint added in v0.7.0

type IterableSizeHint interface {
	SizeHint() (uint, Option[uint])
}

IterableSizeHint represents an iterable that can provide size hints.

type LazyValue added in v1.5.1

type LazyValue[T any] struct {
	// contains filtered or unexported fields
}

LazyValue a value that can be lazily initialized once and read concurrently.

func NewLazyValue added in v1.5.2

func NewLazyValue[T any]() *LazyValue[T]

NewLazyValue new empty LazyValue.

func NewLazyValueWithFunc added in v1.5.2

func NewLazyValueWithFunc[T any](onceInit func() Result[T]) *LazyValue[T]

NewLazyValueWithFunc new LazyValue with initialization function. The value will be computed lazily when TryGetValue() is called.

func NewLazyValueWithValue added in v1.5.2

func NewLazyValueWithValue[T any](v T) *LazyValue[T]

NewLazyValueWithValue new LazyValue with initialization value. The value will be computed lazily when TryGetValue() is called.

func NewLazyValueWithZero added in v1.5.2

func NewLazyValueWithZero[T any]() *LazyValue[T]

NewLazyValueWithZero new LazyValue with zero. The value will be computed lazily when TryGetValue() is called.

func (*LazyValue[T]) GetPtr added in v1.5.1

func (o *LazyValue[T]) GetPtr() *T

GetPtr returns its pointer or nil.

func (*LazyValue[T]) IsInitialized added in v1.5.1

func (o *LazyValue[T]) IsInitialized() bool

IsInitialized determine whether it is initialized.

func (*LazyValue[T]) SetInitFunc added in v1.5.2

func (o *LazyValue[T]) SetInitFunc(onceInit func() Result[T]) *LazyValue[T]

SetInitFunc set initialization function. NOTE: onceInit can not be nil If the LazyValue already has an initialization function set (even if not initialized yet), this function will not override it.

func (*LazyValue[T]) SetInitValue added in v1.5.2

func (o *LazyValue[T]) SetInitValue(v T) *LazyValue[T]

SetInitValue set the initialization value.

func (*LazyValue[T]) SetInitZero added in v1.5.2

func (o *LazyValue[T]) SetInitZero() *LazyValue[T]

SetInitZero set the zero value for initialization.

func (*LazyValue[T]) TryGetValue added in v1.5.1

func (o *LazyValue[T]) TryGetValue() Result[T]

TryGetValue concurrency-safe get the Result[T].

func (*LazyValue[T]) Zero added in v1.5.2

func (*LazyValue[T]) Zero() T

Zero creates a zero T.

type Mutex added in v1.2.2

type Mutex[T any] struct {
	// contains filtered or unexported fields
}

Mutex is a better generic-type wrapper for `sync.Mutex` that holds a value. A Mutex is a mutual exclusion lock. The zero value for a Mutex is an unlocked mutex.

A Mutex must not be copied after first use.

In the terminology of the Go memory model, the n'th call to Unlock “synchronizes before” the m'th call to Lock for any n < m. A successful call to TryLock is equivalent to a call to Lock. A failed call to TryLock does not establish any “synchronizes before” relation at all.

func NewMutex added in v1.2.2

func NewMutex[T any](data T) *Mutex[T]

NewMutex returns a new *Mutex.

func (*Mutex[T]) Lock added in v1.2.2

func (m *Mutex[T]) Lock() T

Lock locks m. If the lock is already in use, the calling goroutine blocks until the mutex is available.

func (*Mutex[T]) LockScope added in v1.5.0

func (m *Mutex[T]) LockScope(f func(old T) (new T))

LockScope securely read and write the data in the Mutex[T].

func (*Mutex[T]) TryLock added in v1.2.2

func (m *Mutex[T]) TryLock() Option[T]

TryLock tries to lock m and reports whether it succeeded.

Note that while correct uses of TryLock do exist, they are rare, and use of TryLock is often a sign of a deeper problem in a particular use of mutexes.

func (*Mutex[T]) TryLockScope added in v1.5.0

func (m *Mutex[T]) TryLockScope(f func(old T) (new T))

TryLockScope tries to securely read and write the data in the Mutex[T].

func (*Mutex[T]) Unlock added in v1.2.2

func (m *Mutex[T]) Unlock(newData ...T)

Unlock unlocks m. It is a run-time error if m is not locked on entry to Unlock.

A locked Mutex is not associated with a particular goroutine. It is allowed for one goroutine to lock a Mutex and then arrange for another goroutine to unlock it.

type Option

type Option[T any] struct {
	// contains filtered or unexported fields
}

Option can be used to avoid `(T, bool)` and `if *U != nil`, represents an optional value:

every [`Option`] is either [`Some`](which is non-none T), or [`None`](which is none).
Example
package main

import (
	"fmt"
	"strconv"

	"github.com/andeya/gust"
	"github.com/andeya/gust/opt"
)

func main() {
	type A struct {
		X int
	}
	var a = gust.Some(A{X: 1})
	fmt.Println(a.IsSome(), a.IsNone())

	var b = gust.None[A]()
	fmt.Println(b.IsSome(), b.IsNone())

	var x = b.UnwrapOr(A{X: 2})
	fmt.Println(x)

	var c *A
	fmt.Println(gust.PtrOpt(c).IsNone())
	fmt.Println(gust.ElemOpt(c).IsNone())
	c = new(A)
	fmt.Println(gust.PtrOpt(c).IsNone())
	fmt.Println(gust.ElemOpt(c).IsNone())

	type B struct {
		Y string
	}
	var d = opt.Map(a, func(t A) B {
		return B{
			Y: strconv.Itoa(t.X),
		}
	})
	fmt.Println(d)

}
Output:
true false
false true
{2}
true
true
false
false
Some({1})

func AssertOpt added in v1.4.0

func AssertOpt[T any](i any) Option[T]

AssertOpt returns the Option[T] of asserting `i` to type `T`

func BoolAssertOpt added in v1.4.0

func BoolAssertOpt[T any](i any, ok bool) Option[T]

BoolAssertOpt wraps a value as an Option. NOTE:

`ok=true` is wrapped as Some,
and `ok=false` is wrapped as None.

func BoolOpt added in v1.0.0

func BoolOpt[T any](value T, ok bool) Option[T]

BoolOpt wraps a value as an Option. NOTE:

`ok=true` is wrapped as Some,
and `ok=false` is wrapped as None.

func ElemOpt added in v1.2.2

func ElemOpt[T any](ptr *T) Option[T]

ElemOpt wraps a value from pointer. NOTE:

`non-nil pointer` is wrapped as Some,
and `nil pointer` is wrapped as None.

func None

func None[T any]() Option[T]

None returns a none. NOTE:

Option[T].IsNone() returns true,
and Option[T].IsSome() returns false.

func PtrOpt added in v1.0.0

func PtrOpt[U any, T *U](ptr T) Option[T]

PtrOpt wraps a pointer value. NOTE:

`non-nil pointer` is wrapped as Some,
and `nil pointer` is wrapped as None.

func RetAnyOpt added in v1.8.0

func RetAnyOpt[T any](value any, err error) Option[any]

RetAnyOpt wraps a value as an `Option[any]`. NOTE:

`err != nil` or `value`==nil is wrapped as None,
and `err == nil` and `value != nil` is wrapped as Some.

func RetOpt added in v1.8.0

func RetOpt[T any](value T, err error) Option[T]

RetOpt wraps a value as an `Option[T]`. NOTE:

`err != nil` is wrapped as None,
and `err == nil` is wrapped as Some.

func Some

func Some[T any](value T) Option[T]

Some wraps a non-none value. NOTE:

Option[T].IsSome() returns true.
and Option[T].IsNone() returns false.

func ZeroOpt added in v1.0.0

func ZeroOpt[T comparable](value T) Option[T]

ZeroOpt wraps a value as an Option. NOTE:

`non-zero T` is wrapped as Some,
and `zero T` is wrapped as None.

func (Option[T]) And

func (o Option[T]) And(optb Option[T]) Option[T]

And returns [`None`] if the option is [`None`], otherwise returns `optb`.

func (Option[T]) AndThen

func (o Option[T]) AndThen(f func(T) Option[T]) Option[T]

AndThen returns [`None`] if the option is [`None`], otherwise calls `f` with the

func (*Option[T]) AsPtr added in v1.4.3

func (o *Option[T]) AsPtr() *T

AsPtr returns its pointer or nil.

func (Option[T]) Expect

func (o Option[T]) Expect(msg string) T

Expect returns the contained [`Some`] value. Panics if the value is none with a custom panic message provided by `msg`.

func (Option[T]) Filter

func (o Option[T]) Filter(predicate func(T) bool) Option[T]

Filter returns [`None`] if the option is [`None`], otherwise calls `predicate` with the wrapped value and returns.

func (*Option[T]) GetOrInsert

func (o *Option[T]) GetOrInsert(some T) *T

GetOrInsert inserts `value` into the option if it is [`None`], then returns the contained value pointer.

func (*Option[T]) GetOrInsertDefault added in v1.4.3

func (o *Option[T]) GetOrInsertDefault() *T

GetOrInsertDefault inserts default value into the option if it is [`None`], then returns the contained value pointer.

func (*Option[T]) GetOrInsertWith

func (o *Option[T]) GetOrInsertWith(f func() T) *T

GetOrInsertWith inserts a value computed from `f` into the option if it is [`None`], then returns the contained value.

func (*Option[T]) Insert

func (o *Option[T]) Insert(some T) *T

Insert inserts `value` into the option, then returns its pointer.

func (Option[T]) Inspect

func (o Option[T]) Inspect(f func(T)) Option[T]

Inspect calls the provided closure with a reference to the contained value (if it has value).

Example
package main

import (
	"fmt"

	"github.com/andeya/gust"
)

func main() {
	// prints "got: 3"
	_ = gust.Some(3).Inspect(func(x int) {
		fmt.Println("got:", x)
	})

	// prints nothing
	_ = gust.None[int]().Inspect(func(x int) {
		fmt.Println("got:", x)
	})

}
Output:
got: 3

func (Option[T]) InspectNone

func (o Option[T]) InspectNone(f func()) Option[T]

InspectNone calls the provided closure (if it is none).

func (Option[T]) IsNone

func (o Option[T]) IsNone() bool

IsNone returns `true` if the option is none.

func (Option[T]) IsSome

func (o Option[T]) IsSome() bool

IsSome returns `true` if the option has value.

func (Option[T]) IsSomeAnd

func (o Option[T]) IsSomeAnd(f func(T) bool) bool

IsSomeAnd returns `true` if the option has value and the value inside it matches a predicate.

func (Option[T]) Map

func (o Option[T]) Map(f func(T) T) Option[T]

Map maps an `Option[T]` to `Option[T]` by applying a function to a contained value.

func (Option[T]) MapOr

func (o Option[T]) MapOr(defaultSome T, f func(T) T) T

MapOr returns the provided default value (if none), or applies a function to the contained value (if any).

func (Option[T]) MapOrElse

func (o Option[T]) MapOrElse(defaultFn func() T, f func(T) T) T

MapOrElse computes a default function value (if none), or applies a different function to the contained value (if any).

func (Option[T]) MarshalJSON added in v0.6.0

func (o Option[T]) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (*Option[T]) Next added in v0.7.0

func (o *Option[T]) Next() Option[T]

Next returns the next element of the iterator.

func (*Option[T]) NextBack added in v0.7.0

func (o *Option[T]) NextBack() Option[T]

NextBack returns the next element from the back of the iterator.

func (Option[T]) OkOr

func (o Option[T]) OkOr(err any) Result[T]

OkOr transforms the `Option[T]` into a [`Result[T]`], mapping [`Some(v)`] to [`Ok(v)`] and [`None`] to [`Err(err)`].

func (Option[T]) OkOrElse

func (o Option[T]) OkOrElse(errFn func() any) Result[T]

OkOrElse transforms the `Option[T]` into a [`Result[T]`], mapping [`Some(v)`] to [`Ok(v)`] and [`None`] to [`Err(errFn())`].

func (Option[T]) Or

func (o Option[T]) Or(optb Option[T]) Option[T]

Or returns the option if it contains a value, otherwise returns `optb`.

func (Option[T]) OrElse

func (o Option[T]) OrElse(f func() Option[T]) Option[T]

OrElse returns the option if it contains a value, otherwise calls `f` and returns the result.

func (Option[T]) Ref added in v1.5.5

func (o Option[T]) Ref() *Option[T]

Ref returns the pointer of the object.

func (*Option[T]) Remaining added in v0.7.0

func (o *Option[T]) Remaining() uint

Remaining returns the number of remaining elements in the iterator.

func (*Option[T]) Replace

func (o *Option[T]) Replace(some T) (old Option[T])

Replace replaces the actual value in the option by the value given in parameter, returning the old value if present, leaving a [`Some`] in its place without deinitializing either one.

func (Option[T]) Split added in v1.4.4

func (o Option[T]) Split() (T, bool)

Split returns the tuple (T, bool).

func (Option[T]) String

func (o Option[T]) String() string

String returns the string representation.

func (*Option[T]) Take added in v0.7.0

func (o *Option[T]) Take() Option[T]

Take takes the value out of the option, leaving a [`None`] in its place.

func (Option[T]) ToResult added in v1.11.0

func (o Option[T]) ToResult() VoidResult

ToResult converts from `Option[T]` to `VoidResult` (Result[Void]). If Option is Some, returns Err[Void] with the value wrapped in ErrBox. If Option is None, returns Ok[Void](nil).

Example:

```go
var opt gust.Option[string] = gust.Some("value")
var result gust.VoidResult = opt.ToResult()
```

func (Option[T]) ToX added in v0.7.0

func (o Option[T]) ToX() Option[any]

ToX converts to `Option[any]`.

func (*Option[T]) UnmarshalJSON added in v0.6.0

func (o *Option[T]) UnmarshalJSON(b []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

func (Option[T]) Unwrap

func (o Option[T]) Unwrap() T

Unwrap returns the contained value. Panics if the value is none.

func (Option[T]) UnwrapOr

func (o Option[T]) UnwrapOr(fallbackValue T) T

UnwrapOr returns the contained value or a provided fallback value.

func (Option[T]) UnwrapOrDefault added in v1.3.3

func (o Option[T]) UnwrapOrDefault() T

UnwrapOrDefault returns the contained value or a non-nil-pointer zero value.

func (Option[T]) UnwrapOrElse

func (o Option[T]) UnwrapOrElse(defaultSome func() T) T

UnwrapOrElse returns the contained value or computes it from a closure.

func (Option[T]) UnwrapOrThrow added in v1.5.3

func (r Option[T]) UnwrapOrThrow(err any) T

UnwrapOrThrow returns the contained T or panic returns error (*ErrBox). NOTE:

If there is an error, that panic should be caught with `Result.Catch()`

func (Option[T]) UnwrapUnchecked

func (o Option[T]) UnwrapUnchecked() T

UnwrapUnchecked returns the contained value.

func (Option[T]) XAnd added in v0.7.0

func (o Option[T]) XAnd(optb Option[any]) Option[any]

XAnd returns [`None`] if the option is [`None`], otherwise returns `optb`.

func (Option[T]) XAndThen added in v0.7.0

func (o Option[T]) XAndThen(f func(T) Option[any]) Option[any]

XAndThen returns [`None`] if the option is [`None`], otherwise calls `f` with the

func (Option[T]) XMap added in v0.7.0

func (o Option[T]) XMap(f func(T) any) Option[any]

XMap maps an `Option[T]` to `Option[any]` by applying a function to a contained value.

func (Option[T]) XMapOr added in v0.7.0

func (o Option[T]) XMapOr(defaultSome any, f func(T) any) any

XMapOr returns the provided default value (if none), or applies a function to the contained value (if any).

func (Option[T]) XMapOrElse added in v0.7.0

func (o Option[T]) XMapOrElse(defaultFn func() any, f func(T) any) any

XMapOrElse computes a default function value (if none), or applies a different function to the contained value (if any).

func (Option[T]) XOkOr added in v1.0.0

func (o Option[T]) XOkOr(err any) Result[any]

XOkOr transforms the `Option[T]` into a [`Result[any]`], mapping [`Some(v)`] to [`Ok(v)`] and [`None`] to [`Err(err)`].

func (Option[T]) XOkOrElse added in v1.0.0

func (o Option[T]) XOkOrElse(errFn func() any) Result[any]

XOkOrElse transforms the `Option[T]` into a [`Result[any]`], mapping [`Some(v)`] to [`Ok(v)`] and [`None`] to [`Err(errFn())`].

func (Option[T]) Xor added in v0.7.0

func (o Option[T]) Xor(optb Option[T]) Option[T]

Xor [`Some`] if exactly one of `self`, `optb` is [`Some`], otherwise returns [`None`].

type Ord added in v1.1.2

type Ord interface {
	Digit | ~string | ~uintptr
}

Ord represents types that can be ordered (compared).

type Ordering added in v1.1.2

type Ordering struct {
	// contains filtered or unexported fields
}

Ordering represents the result of a comparison between two values.

func Compare added in v1.1.2

func Compare[T Ord](a, b T) Ordering

Compare compares two values and returns their Ordering.

func Equal added in v1.1.2

func Equal() Ordering

Equal returns an Ordering representing "equal".

func Greater added in v1.1.2

func Greater() Ordering

Greater returns an Ordering representing "greater than".

func Less added in v1.1.2

func Less() Ordering

Less returns an Ordering representing "less than".

func (Ordering) Is added in v1.1.2

func (o Ordering) Is(ord Ordering) bool

Is checks if this Ordering matches the given Ordering.

func (Ordering) IsEqual added in v1.1.2

func (o Ordering) IsEqual() bool

IsEqual returns true if this Ordering represents "equal".

func (Ordering) IsGreater added in v1.1.2

func (o Ordering) IsGreater() bool

IsGreater returns true if this Ordering represents "greater than".

func (Ordering) IsLess added in v1.1.2

func (o Ordering) IsLess() bool

IsLess returns true if this Ordering represents "less than".

type Pair added in v0.7.0

type Pair[A any, B any] struct {
	A A
	B B
}

Pair is a pair of values.

func (Pair[A, B]) Split added in v1.9.1

func (p Pair[A, B]) Split() (A, B)

Split splits the pair into its two components.

type PureInteger added in v1.1.2

type PureInteger interface {
	int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64
}

PureInteger represents pure integer types without type aliases.

type RWMutex added in v1.2.2

type RWMutex[T any] struct {
	// contains filtered or unexported fields
}

RWMutex is a better generic-type wrapper for `sync.RWMutex` that holds a value. A RWMutex is a reader/writer mutual exclusion lock. The lock can be held by an arbitrary number of readers or a single writer. The zero value for a RWMutex is an unlocked mutex.

A RWMutex must not be copied after first use.

If a goroutine holds a RWMutex for reading and another goroutine might call Lock, no goroutine should expect to be able to acquire a read lock until the initial read lock is released. In particular, this prohibits recursive read locking. This is to ensure that the lock eventually becomes available; a blocked Lock call excludes new readers from acquiring the lock.

In the terminology of the Go memory model, the n'th call to Unlock “synchronizes before” the m'th call to Lock for any n < m, just as for Mutex. For any call to RLock, there exists an n such that the n'th call to Unlock “synchronizes before” that call to RLock, and the corresponding call to RUnlock “synchronizes before” the n+1'th call to Lock.

func NewRWMutex added in v1.2.2

func NewRWMutex[T any](data T) *RWMutex[T]

NewRWMutex returns a new *RWMutex.

func (*RWMutex[T]) Lock added in v1.2.2

func (m *RWMutex[T]) Lock() T

Lock locks rw for writing. If the lock is already locked for reading or writing, Lock blocks until the lock is available.

func (*RWMutex[T]) LockScope added in v1.5.0

func (m *RWMutex[T]) LockScope(write func(old T) (new T))

LockScope securely read and write the data in the RWMutex[T].

func (*RWMutex[T]) RLock added in v1.2.2

func (m *RWMutex[T]) RLock() T

RLock locks rw for reading.

It should not be used for recursive read locking; a blocked Lock call excludes new readers from acquiring the lock. See the documentation on the RWMutex type.

func (*RWMutex[T]) RLockScope added in v1.5.0

func (m *RWMutex[T]) RLockScope(read func(T))

RLockScope securely read the data in the RWMutex[T].

func (*RWMutex[T]) RUnlock added in v1.2.2

func (m *RWMutex[T]) RUnlock()

RUnlock undoes a single RLock call; it does not affect other simultaneous readers. It is a run-time error if rw is not locked for reading on entry to RUnlock.

func (*RWMutex[T]) TryBest added in v1.5.0

func (m *RWMutex[T]) TryBest(readAndDo func(T) bool, swapWhenFalse func(old T) (new Option[T]))

TryBest tries to read and do the data in the RWMutex[T] safely, swapping the data when readAndDo returns false and then trying to do again.

func (*RWMutex[T]) TryLock added in v1.2.2

func (m *RWMutex[T]) TryLock() Option[T]

TryLock tries to lock rw for writing and reports whether it succeeded.

Note that while correct uses of TryLock do exist, they are rare, and use of TryLock is often a sign of a deeper problem

func (*RWMutex[T]) TryLockScope added in v1.5.0

func (m *RWMutex[T]) TryLockScope(write func(old T) (new T))

TryLockScope tries to securely read and write the data in the RWMutex[T].

func (*RWMutex[T]) TryRLock added in v1.2.2

func (m *RWMutex[T]) TryRLock() Option[T]

TryRLock tries to lock rw for reading and reports whether it succeeded.

Note that while correct uses of TryRLock do exist, they are rare, and use of TryRLock is often a sign of a deeper problem in a particular use of mutexes.

func (*RWMutex[T]) TryRLockScope added in v1.5.0

func (m *RWMutex[T]) TryRLockScope(read func(T))

TryRLockScope tries to securely read the data in the RWMutex[T].

func (*RWMutex[T]) Unlock added in v1.2.2

func (m *RWMutex[T]) Unlock(newData ...T)

Unlock unlocks rw for writing. It is a run-time error if rw is not locked for writing on entry to Unlock.

As with Mutexes, a locked RWMutex is not associated with a particular goroutine. One goroutine may RLock (Lock) a RWMutex and then arrange for another goroutine to RUnlock (Unlock) it.

type Result

type Result[T any] struct {
	// contains filtered or unexported fields
}

Result can be used to improve `func()(T,error)`, represents either success (T) or failure (error).

func AssertRet added in v1.5.6

func AssertRet[T any](i any) Result[T]

AssertRet returns the Result[T] of asserting `i` to type `T`

func Err

func Err[T any](err any) Result[T]

Err wraps a failure result. NOTE: Even if err is nil, Err(nil) still represents an error state. This follows declarative programming principles: calling Err() explicitly declares an error result, regardless of the error value. This is consistent with Rust's Result::Err(()) semantics.

Example:

```go
result := gust.Err[string](nil)  // This is an error state, even though err is nil
if result.IsErr() {
	fmt.Println("This will be printed")
}
```

func FmtErr added in v1.5.4

func FmtErr[T any](format string, a ...any) Result[T]

FmtErr wraps a failure result with a formatted error.

func Ok

func Ok[T any](ok T) Result[T]

Ok wraps a successful result.

func Ret

func Ret[T any](some T, err error) Result[T]

Ret wraps a result.

func (Result[T]) And

func (r Result[T]) And(r2 Result[T]) Result[T]

And returns `r` if `r` is `Err`, otherwise returns `r2`.

func (Result[T]) And2 added in v1.8.0

func (r Result[T]) And2(v2 T, err2 error) Result[T]

And2 returns `r` if `r` is `Err`, otherwise returns `Ret(v2, err2)`.

func (Result[T]) AndThen

func (r Result[T]) AndThen(op func(T) Result[T]) Result[T]

AndThen calls op if the result is Ok, otherwise returns the error of self. This function can be used for control flow based on Result values.

Example
package main

import (
	"fmt"

	"github.com/andeya/gust"
)

func main() {
	var divide = func(i, j float32) gust.Result[float32] {
		if j == 0 {
			return gust.Err[float32]("j can not be 0")
		}
		return gust.Ok(i / j)
	}
	var ret float32 = divide(1, 2).AndThen(func(i float32) gust.Result[float32] {
		return gust.Ok(i * 10)
	}).Unwrap()
	fmt.Println(ret)
}
Output:
5

func (Result[T]) AndThen2 added in v1.8.0

func (r Result[T]) AndThen2(op func(T) (T, error)) Result[T]

AndThen2 calls op if the result is Ok, otherwise returns the error of self. This function can be used for control flow based on Result values.

func (Result[T]) AsPtr added in v1.5.2

func (r Result[T]) AsPtr() *T

AsPtr returns its pointer or nil.

func (*Result[T]) Catch added in v1.5.3

func (r *Result[T]) Catch(withStackTrace ...bool)

Catch catches any panic and converts it to a Result error. It catches:

  • *ErrBox (gust's own error type)
  • error (regular Go errors, wrapped in ErrBox)
  • any other type (wrapped in ErrBox)

When a panic is caught, Catch can optionally capture the panic stack trace using PanicStackTrace() and wrap it with the error for better debugging. By default, stack trace is captured (withStackTrace defaults to true). Set withStackTrace to false to disable stack trace capture for better performance.

Example:

```go
func example() (result Result[string]) {
   defer result.Catch()  // With stack trace (default)
   Err[int]("int error").UnwrapOrThrow()
   return Ok[string]("ok")
}

func exampleNoStack() (result Result[string]) {
   defer result.Catch(false)  // Without stack trace
   Err[int]("int error").UnwrapOrThrow()
   return Ok[string]("ok")
}
```

func (Result[T]) ContainsErr

func (r Result[T]) ContainsErr(err any) bool

ContainsErr returns true if the result is an error containing the given value.

func (Result[T]) Err

func (r Result[T]) Err() error

Err returns error.

func (Result[T]) ErrVal

func (r Result[T]) ErrVal() any

ErrVal returns error inner value.

func (Result[T]) Expect

func (r Result[T]) Expect(msg string) T

Expect returns the contained Ok value. Panics if the value is an error, with a panic message including the passed message, and the content of the error.

func (Result[T]) ExpectErr

func (r Result[T]) ExpectErr(msg string) error

ExpectErr returns the contained error. Panics if the value is not an error, with a panic message including the passed message, and the content of the [`Ok`].

func (Result[T]) Flatten added in v1.8.0

func (r Result[T]) Flatten(err error) Result[T]

Flatten converts from `(gust.Result[T], error)` to gust.Result[T].

Examples

var r1 = gust.Ok(1)
var err1 = nil
var result1 = r1.Flatten(err1)
assert.Equal(t, gust.Ok[int](1), result1)

var r2 = gust.Ok(1)
var err2 = errors.New("error")
var result2 = r2.Flatten(err2)
assert.Equal(t, "error", result2.Err().Error())

var r3 = gust.Err(errors.New("error")) var err3 = nil var result3 = r3.Flatten(err3) assert.Equal(t, "error", result3.Err().Error())

func (Result[T]) Inspect

func (r Result[T]) Inspect(f func(T)) Result[T]

Inspect calls the provided closure with a reference to the contained value (if no error).

func (Result[T]) InspectErr

func (r Result[T]) InspectErr(f func(error)) Result[T]

InspectErr calls the provided closure with a reference to the contained error (if error).

func (Result[T]) IsErr

func (r Result[T]) IsErr() bool

IsErr returns true if the result is error. NOTE: This is determined by whether t.IsSome() is false, not by e.IsEmpty(). This ensures that Err(nil) is correctly identified as an error state, following declarative programming principles where Err() explicitly declares an error result.

func (Result[T]) IsErrAnd

func (r Result[T]) IsErrAnd(f func(error) bool) bool

IsErrAnd returns true if the result is error and the value inside it matches a predicate.

func (Result[T]) IsOk

func (r Result[T]) IsOk() bool

IsOk returns true if the result is Ok. NOTE: This is determined by whether t.IsSome() is true, not by e.IsEmpty(). This ensures that Err(nil) is correctly identified as an error state, following declarative programming principles where Err() explicitly declares an error result.

func (Result[T]) IsOkAnd

func (r Result[T]) IsOkAnd(f func(T) bool) bool

IsOkAnd returns true if the result is Ok and the value inside it matches a predicate.

func (*Result[T]) IsValid added in v1.4.0

func (r *Result[T]) IsValid() bool

IsValid returns true if the object is initialized.

func (Result[T]) Map

func (r Result[T]) Map(f func(T) T) Result[T]

Map maps a Result[T] to Result[T] by applying a function to a contained Ok value, leaving an error untouched. This function can be used to compose the results of two functions.

func (Result[T]) MapErr

func (r Result[T]) MapErr(op func(error) (newErr any)) Result[T]

MapErr maps a Result[T] to Result[T] by applying a function to a contained error, leaving an Ok value untouched. This function can be used to pass through a successful result while handling an error.

func (Result[T]) MapOr

func (r Result[T]) MapOr(defaultOk T, f func(T) T) T

MapOr returns the provided default (if error), or applies a function to the contained value (if no error), Arguments passed to map_or are eagerly evaluated; if you are passing the result of a function call, it is recommended to use MapOrElse, which is lazily evaluated.

func (Result[T]) MapOrElse

func (r Result[T]) MapOrElse(defaultFn func(error) T, f func(T) T) T

MapOrElse maps a Result[T] to T by applying fallback function default to a contained error, or function f to a contained Ok value. This function can be used to unpack a successful result while handling an error.

func (Result[T]) MarshalJSON added in v0.6.0

func (r Result[T]) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (*Result[T]) Next added in v0.7.0

func (r *Result[T]) Next() Option[T]

Next returns the next element of the iterator.

func (*Result[T]) NextBack added in v0.7.0

func (r *Result[T]) NextBack() Option[T]

NextBack returns the next element from the back of the iterator.

func (Result[T]) Ok

func (r Result[T]) Ok() Option[T]

Ok converts from `Result[T]` to `Option[T]`.

func (Result[T]) Or

func (r Result[T]) Or(r2 Result[T]) Result[T]

Or returns `r2` if `r` is `Err`, otherwise returns `r`. Arguments passed to or are eagerly evaluated; if you are passing the result of a function call, it is recommended to use OrElse, which is lazily evaluated.

func (Result[T]) Or2 added in v1.8.0

func (r Result[T]) Or2(v2 T, err2 error) Result[T]

Or2 returns `Ret(v2, err2)` if `r` is `Err`, otherwise returns `r`.

func (Result[T]) OrElse

func (r Result[T]) OrElse(op func(error) Result[T]) Result[T]

OrElse calls op if the result is Err, otherwise returns the Ok value of self. This function can be used for control flow based on result values.

func (Result[T]) OrElse2 added in v1.8.0

func (r Result[T]) OrElse2(op func(error) (T, error)) Result[T]

OrElse2 calls op if the result is Err, otherwise returns the Ok value of self. This function can be used for control flow based on result values.

func (Result[T]) Ref added in v1.5.5

func (r Result[T]) Ref() *Result[T]

Ref returns the pointer of the object.

func (*Result[T]) Remaining added in v0.7.0

func (r *Result[T]) Remaining() uint

Remaining returns the number of remaining elements in the iterator.

func (Result[T]) Split added in v1.4.4

func (r Result[T]) Split() (T, error)

Split returns the tuple (T, error).

func (Result[T]) String

func (r Result[T]) String() string

String returns the string representation.

func (Result[T]) ToX added in v0.7.0

func (r Result[T]) ToX() Result[any]

ToX converts from `Result[T]` to Result[any].

func (*Result[T]) UnmarshalJSON added in v0.6.0

func (r *Result[T]) UnmarshalJSON(b []byte) error

UnmarshalJSON implements the json.Unmarshaler interface.

func (Result[T]) Unwrap

func (r Result[T]) Unwrap() T

Unwrap returns the contained Ok value. Because this function may panic, its use is generally discouraged. Instead, prefer to use pattern matching and handle the error case explicitly, or call UnwrapOr or UnwrapOrElse. NOTE: This panics *ErrBox (not error) to be consistent with Result.UnwrapOrThrow() and allow Result.Catch() to properly handle it.

func (Result[T]) UnwrapErr

func (r Result[T]) UnwrapErr() error

UnwrapErr returns the contained error. Panics if the value is not an error, with a custom panic message provided by the [`Ok`]'s value.

func (Result[T]) UnwrapOr

func (r Result[T]) UnwrapOr(defaultOk T) T

UnwrapOr returns the contained Ok value or a provided default. Arguments passed to UnwrapOr are eagerly evaluated; if you are passing the result of a function call, it is recommended to use UnwrapOrElse, which is lazily evaluated.

Example
package main

import (
	"fmt"
	"strconv"

	"github.com/andeya/gust"
)

func main() {
	const def int = 10

	// before
	i, err := strconv.Atoi("1")
	if err != nil {
		i = def
	}
	fmt.Println(i * 2)

	// now
	fmt.Println(gust.Ret(strconv.Atoi("1")).UnwrapOr(def) * 2)

}
Output:
2
2

func (Result[T]) UnwrapOrDefault added in v1.4.0

func (r Result[T]) UnwrapOrDefault() T

UnwrapOrDefault returns the contained T or a non-nil-pointer zero T.

func (Result[T]) UnwrapOrElse

func (r Result[T]) UnwrapOrElse(defaultFn func(error) T) T

UnwrapOrElse returns the contained Ok value or computes it from a closure.

func (Result[T]) UnwrapOrThrow added in v1.4.2

func (r Result[T]) UnwrapOrThrow() T

UnwrapOrThrow returns the contained T or panic returns error (*ErrBox). NOTE:

If there is an error, that panic should be caught with `Result.Catch()`

func (Result[T]) UnwrapUnchecked

func (r Result[T]) UnwrapUnchecked() T

UnwrapUnchecked returns the contained T.

func (Result[T]) XAnd added in v0.7.0

func (r Result[T]) XAnd(res Result[any]) Result[any]

XAnd returns res if the result is Ok, otherwise returns the error of self.

func (Result[T]) XAnd2 added in v1.8.0

func (r Result[T]) XAnd2(v2 any, err2 error) Result[any]

XAnd2 returns `r` if `r` is `Err`, otherwise returns `Ret(v2, err2)`.

func (Result[T]) XAndThen added in v0.7.0

func (r Result[T]) XAndThen(op func(T) Result[any]) Result[any]

XAndThen calls op if the result is Ok, otherwise returns the error of self. This function can be used for control flow based on Result values.

func (Result[T]) XAndThen2 added in v1.8.0

func (r Result[T]) XAndThen2(op func(T) (any, error)) Result[any]

XAndThen2 calls op if the result is Ok, otherwise returns the error of self. This function can be used for control flow based on Result values.

func (Result[T]) XMap added in v0.7.0

func (r Result[T]) XMap(f func(T) any) Result[any]

XMap maps a Result[T] to Result[any] by applying a function to a contained Ok value, leaving an error untouched. This function can be used to compose the results of two functions.

func (Result[T]) XMapOr added in v0.7.0

func (r Result[T]) XMapOr(defaultOk any, f func(T) any) any

XMapOr returns the provided default (if error), or applies a function to the contained value (if no error), Arguments passed to map_or are eagerly evaluated; if you are passing the result of a function call, it is recommended to use MapOrElse, which is lazily evaluated.

func (Result[T]) XMapOrElse added in v0.7.0

func (r Result[T]) XMapOrElse(defaultFn func(error) any, f func(T) any) any

XMapOrElse maps a Result[T] to `any` by applying fallback function default to a contained error, or function f to a contained Ok value. This function can be used to unpack a successful result while handling an error.

func (Result[T]) XOk added in v1.0.0

func (r Result[T]) XOk() Option[any]

XOk converts from `Result[T]` to `Option[any]`.

type SizeIterable added in v0.7.0

type SizeIterable[T any] interface {
	Remaining() uint
}

SizeIterable represents an iterable that knows its remaining size.

type StackTrace added in v1.12.0

type StackTrace []Frame

StackTrace is stack of Frames from innermost (newest) to outermost (oldest).

func GetStackTrace added in v1.12.0

func GetStackTrace(skip int) StackTrace

GetStackTrace gets the stack trace.

func PanicStackTrace added in v1.12.0

func PanicStackTrace() StackTrace

PanicStackTrace gets the panic stack trace.

func (StackTrace) Format added in v1.12.0

func (st StackTrace) Format(s fmt.State, verb rune)

Format formats the stack of Frames according to the fmt.Formatter interface.

%s	lists source files for each Frame in the stack
%v	lists the source file and line number for each Frame in the stack
%d	lists line numbers for each Frame in the stack
%n	lists function names for each Frame in the stack

Format accepts flags that alter the printing of some verbs, as follows:

%+v   Prints filename, function, and line number for each Frame in the stack.

type StackTraceCarrier added in v1.12.0

type StackTraceCarrier interface {
	StackTrace() StackTrace
}

StackTraceCarrier is an interface that can carry a stack trace.

type SyncMap added in v1.4.0

type SyncMap[K any, V any] struct {
	// contains filtered or unexported fields
}

SyncMap is a better generic-type wrapper for `sync.Map`. A SyncMap is like a Go map[interface{}]interface{} but is safe for concurrent use by multiple goroutines without additional locking or coordination. Loads, stores, and deletes run in amortized constant time.

The SyncMap type is specialized. Most code should use a plain Go map instead, with separate locking or coordination, for better type safety and to make it easier to maintain other invariants along with the map content.

The SyncMap type is optimized for two common use cases: (1) when the entry for a given key is only ever written once but read many times, as in caches that only grow, or (2) when multiple goroutines read, write, and overwrite entries for disjoint sets of keys. In these two cases, use of a SyncMap may significantly reduce lock contention compared to a Go map paired with a separate Mutex or RWMutex.

The zero SyncMap is empty and ready for use. A SyncMap must not be copied after first use.

In the terminology of the Go memory model, SyncMap arranges that a write operation “synchronizes before” any read operation that observes the effect of the write, where read and write operations are defined as follows. Load, LoadAndDelete, LoadOrStore are read operations; Delete, LoadAndDelete, and Store are write operations; and LoadOrStore is a write operation when it returns loaded set to false.

func (*SyncMap[K, V]) Delete added in v1.4.0

func (m *SyncMap[K, V]) Delete(key K)

Delete deletes the value for a key.

func (*SyncMap[K, V]) Load added in v1.4.0

func (m *SyncMap[K, V]) Load(key K) Option[V]

Load returns the value stored in the map for a key.

func (*SyncMap[K, V]) LoadAndDelete added in v1.4.0

func (m *SyncMap[K, V]) LoadAndDelete(key K) (deletedValue Option[V])

LoadAndDelete deletes the value for a key, returning the previous value if any.

func (*SyncMap[K, V]) LoadOrStore added in v1.4.0

func (m *SyncMap[K, V]) LoadOrStore(key K, value V) (existingValue Option[V])

LoadOrStore returns the existing value for the key if present. Otherwise, it stores the given value, and returns None.

func (*SyncMap[K, V]) Range added in v1.4.0

func (m *SyncMap[K, V]) Range(f func(key K, value V) bool)

Range calls f sequentially for each key and value present in the map. If f returns false, range stops the iteration.

Range does not necessarily correspond to any consistent snapshot of the SyncMap's contents: no key will be visited more than once, but if the value for any key is stored or deleted concurrently (including by f), Range may reflect any mapping for that key from any point during the Range call. Range does not block other methods on the receiver; even f itself may call any method on m.

Range may be O(N) with the number of elements in the map even if f returns false after a constant number of calls.

func (*SyncMap[K, V]) Store added in v1.4.0

func (m *SyncMap[K, V]) Store(key K, value V)

Store sets the value for a key.

type VecEntry added in v1.3.1

type VecEntry[T any] struct {
	Index int
	Elem  T
}

VecEntry is an index-element entry of slice or array.

func (VecEntry[T]) Split added in v1.9.1

func (v VecEntry[T]) Split() (int, T)

Split splits the vector entry into its two components.

type Void added in v0.7.0

type Void = *struct{}

Void is a type that represents the absence of a value.

type VoidResult added in v1.11.0

type VoidResult = Result[Void]

VoidResult is an alias for Result[Void], representing a result that only indicates success or failure. This is equivalent to Rust's Result<(), E> and provides a simpler API than Result[Void].

Example:

```go
var result gust.VoidResult = gust.RetVoid(err)
if result.IsErr() {
	fmt.Println(result.Err())
}
```

func ErrVoid added in v1.12.0

func ErrVoid(err any) VoidResult

ErrVoid wraps a failure result as VoidResult.

func OkVoid added in v1.12.0

func OkVoid() VoidResult

OkVoid returns Ok[Void](nil).

Example:

```go
var result gust.VoidResult = gust.OkVoid()
```

func RetVoid added in v1.11.0

func RetVoid(maybeError any) VoidResult

RetVoid wraps an error as VoidResult (Result[Void]). Returns Ok[Void](nil) if maybeError is nil, otherwise returns Err[Void](maybeError).

Example:

```go
var result gust.VoidResult = gust.RetVoid(maybeError)
```

Directories

Path Synopsis
Package dict is a package of generic-type functions for map.
Package dict is a package of generic-type functions for map.
Package digit is a package of generic-type functions for digit.
Package digit is a package of generic-type functions for digit.
Package iter provides a complete implementation of Rust's Iterator trait in Go.
Package iter provides a complete implementation of Rust's Iterator trait in Go.
Package ret provides helper functions for working with gust.Result types.
Package ret provides helper functions for working with gust.Result types.
Package valconv is a package that provides a generic-type value converter.
Package valconv is a package that provides a generic-type value converter.
Package vec is a package of generic-type functions for slices.
Package vec is a package of generic-type functions for slices.

Jump to

Keyboard shortcuts

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